|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #75190 Impossible to close PDO connection when extending PdoStatement using $this
Submitted: 2017-09-11 15:58 UTC Modified: -
From: ian at oshaughnessy dot cc Assigned:
Status: Open Package: PDO related
PHP Version: 7.0.23 OS: Debian 9
Private report: No CVE-ID:
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: ian at oshaughnessy dot cc
New email:
PHP Version: OS:


 [2017-09-11 15:58 UTC] ian at oshaughnessy dot cc
The only way to close a PDO connection is to set the resource variable to null (thereby destroying the PDO object); however, when extending the PdoStatement class, it's required that $this is passed as an option to the PDO object for Pdo::ATTR_STATEMENT_CLASS.

In doing this, a reference to the PDO object is created, making it impossible to destroy the PDO object since a lingering reference continues to exist after $pdo is set to null.

The only way to fix this issue is to use Pdo::setAttribute() after the PDO parent constructor has been run.

Test script:

echo "Test 1 (PdoTestBroken)\n";
echo "new PdoTestBroken\n";
$pdo1 = new PdoTestBroken($dsn, $username, $password, []);
echo "Destroy \$pdo\n";
$pdo1 = null;
echo "----------------------------\n\n";

echo "Test 2 (PdoTestWorks)\n";
echo "new PdoTestWorks\n";
$pdo2 = new PdoTestWorks($dsn, $username, $password, []);
echo "Destroy \$pdo\n";
$pdo2 = null;
echo "----------------------------\n\n";

class PdoTestBroken extends Pdo {

	public function __construct($dsn, $username, $passwd, $options) {
		echo "PdoTest1::__construct()\n";
		$options[self::ATTR_STATEMENT_CLASS] = [ 'PdoStatementTest', [ $this, ] ];
		parent::__construct($dsn, $username, $passwd, $options);

	public function __destruct() {
		echo "PdoTest1::__destruct()\n";

class PdoTestWorks extends Pdo {

	public function __construct($dsn, $username, $passwd, $options) {
		echo "PdoTest2::__construct()\n";
		$self = parent::__construct($dsn, $username, $passwd, $options);
		$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, [ 'PdoStatementTest', [ $self, ] ]);

	public function __destruct() {
		echo "PdoTest2::__destruct()\n";

class PdoStatementTest extends PdoStatement {


Expected result:
The connection to close.

Actual result:
The connection does not close due to hidden reference variable.

Script Results:

Test 1 (PdoTestBroken)
new PdoTestBroken
Destroy $pdo

Test 2 (PdoTestWorks)
new PdoTestWorks
Destroy $pdo



Add a Patch

Pull Requests

Add a Pull Request

PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Aug 29 15:01:52 2017 UTC