具有扩展 PDOStatement 的 PDO 在设置为 NULL 时无法断开连接

Posted

技术标签:

【中文标题】具有扩展 PDOStatement 的 PDO 在设置为 NULL 时无法断开连接【英文标题】:PDO with extended PDOStatement cannot disconnect the connection when set NULL 【发布时间】:2015-11-30 01:52:34 【问题描述】:

php 5.5.22 和 5.5.25 中测试

当使用扩展了 PDOStatement 的 PDO 时,mysql 保持连接直到 PHP 脚本完成。

use PDO;

$dbinfoCode = array(
    'userid' => 'userid',
    'password' => 'password',
    'engine' => 'mysql',
    'host' => '192.168.100.2',
    'database' => 'test',
);


for ($i = 0; $i < 10000; $i++) 

    $dsn = sprintf("%s:host=%s;dbname=%s", $dbinfo['engine'], $dbinfo['host'], $dbinfo['database']);

    $pdo = new PDO($dsn, $dbinfo['userid'], $dbinfo['password'], $options);
    $pdo->setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('PDOStatement2', array($pdo)));
    $pdo = null;



class PDOStatement2 extends PDOStatement 

我可以在 MySQL 查询中看到越来越多的堆叠“睡眠”进程。最后,MySQL 抛出错误“Too many connections”。

SHOW PROCESSLIST;

如果PDO::ATTR_STATEMENT_CLASS没有setAttribute,则MySQL连接正常断开。

    $pdo = new PDO($dsn, $dbinfo['userid'], $dbinfo['password'], $options);
    //$pdo->setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('PDOStatement2', array($pdo)));
    $pdo = null;

我不知道这是一个错误还是有其他解决方案。

【问题讨论】:

【参考方案1】:

终于找到了解决办法。

以下语句中的$pdo 对象将被复制

$pdo->setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('PDOStatement2', array($pdo)));

使用&amp;$pdo 而不是$pdo

$pdo->setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('PDOStatement2', array(&$pdo)));

【讨论】:

以上是关于具有扩展 PDOStatement 的 PDO 在设置为 NULL 时无法断开连接的主要内容,如果未能解决你的问题,请参考以下文章

PHP PDO学习小结

数据库抽象层PDO 8-1

带有 PDOStatement 的 PDO 重新连接“mysql 服务器消失”错误

PDO

PHP使用PDOStatement处理结果集

PDO中的预处理