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
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
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-2024 The PHP Group
All rights reserved.
Last updated: Thu Oct 31 23:01:28 2024 UTC