具有扩展 PDOStatement 的 PDO 在设置 NULL 时无法断开连接
PDO with extended PDOStatement cannot disconnect the connection when set NULL
在 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 查询中堆叠的 "Sleep" 进程越来越多。最后,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;
我不知道这是一个错误还是有其他解决方案。
终于找到了解决方法。
以下语句中的$pdo 对象将被复制
$pdo->setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('PDOStatement2', array($pdo)));
使用 &$pdo
而不是 $pdo
。
$pdo->setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('PDOStatement2', array(&$pdo)));
在 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 查询中堆叠的 "Sleep" 进程越来越多。最后,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;
我不知道这是一个错误还是有其他解决方案。
终于找到了解决方法。
以下语句中的$pdo 对象将被复制
$pdo->setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('PDOStatement2', array($pdo)));
使用 &$pdo
而不是 $pdo
。
$pdo->setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('PDOStatement2', array(&$pdo)));