php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #66350 Custom statement class parameters can cause memory (connection) leak
Submitted: 2013-12-25 16:24 UTC Modified: 2017-01-02 14:05 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:0 (0.0%)
From: sea128 at post dot cz Assigned: nikic (profile)
Status: Closed Package: PDO Core
PHP Version: 5.5.7 OS:
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: sea128 at post dot cz
New email:
PHP Version: OS:

 

 [2013-12-25 16:24 UTC] sea128 at post dot cz
Description:
------------
Setting statement class with PDO object as parameter causes cyclic reference which prevent from garbage collection.

Test script:
---------------
// it is not sqlite bug, similar problem is with postgresql
$db = new PDO('sqlite::memory:');

// this line will prevent from garbage collection
$db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDOStatement', array($db)));

// this line will not close connection
unset($db);

// this line will not close connection too
gc_collect_cycles();




Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-01-01 12:27 UTC] felipe@php.net
-Package: PDO related +Package: PDO Core
 [2016-01-14 22:05 UTC] noah at noahheck dot com
I experience this same issue using PHP 5.5.9 and 5.6.11 (both on Ubuntu) and mysql (on Ubuntu or CentOS). I've set up a test to replicate the behavior (note the loop is to establish enough connections to hit the max_connections setting for the mysql server). In my tests, I get the expected output, which shows the last connection is still valid, but if the setAttribute line is un-commented, we will get the error message in the catch block.

<?php

class EPDOStatement extends \PDOStatement
{

}

try
{
	for ($x = 0; $x <= 1000; $x++)
	{

		$pdo = new \PDO("mysql:localhost", "test", "test");

		// $pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS, array("EPDOStatement", array($pdo)));

		if ($x !== 1000)
		{
			$pdo = null;
		}
	}
}
catch (Exception $e)
{
	echo "Exception at number $x: " . $e->getMessage();
	exit;
}

$stmt = $pdo->query("SHOW DATABASES");

print_r($stmt->fetchAll());
 [2017-01-02 14:05 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 [2017-01-02 14:05 UTC] nikic@php.net
This has been fixed in PHP 7.0 by https://github.com/php/php-src/commit/b081da657e4c334edce83e2548df00f502fb4a90. As PHP 5.6 is going out of active support, I'm closing this bug.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Thu Jan 02 12:01:29 2025 UTC