2

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 は「接続が多すぎます」というエラーをスローします。

SHOW PROCESSLIST;

について setAttribute がない場合PDO::ATTR_STATEMENT_CLASS、MySQL 接続は正常に切断されています。

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

これがバグなのか、それとも別の解決策があるのか​​ 、それについてはわかりません。

4

1 に答える 1

2

最後に、解決策を見つけました。

次のステートメントの $pdo オブジェクトが複製されます

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

&$pdoの代わりに使用し$pdoます。

$pdo->setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('PDOStatement2', array(&$pdo)));
于 2015-09-13T15:38:37.000 に答える