5

変数を再利用して、2 つの異なる PDO mysql ステートメントを格納しています。

$stmt=$dbh->prepare("SELECT ....");   
$stmt->execute();

$stmt=$dbh->prepare("UPDATE ....");
//crash here: 
//*** Error in `/opt/lampp/bin/httpd': free(): invalid pointer: 0xf4a028dc ***
//*** Error in `/opt/lampp/bin/httpd': free(): invalid pointer: 0xf4a028dc ***
//[Mon Jun 03 19:53:48.691674 2013] [core:notice] [pid 20249] AH00052: child pid 25933 exit //signal Aborted (6)
//[Mon Jun 03 19:53:48.691727 2013] [core:notice] [pid 20249] AH00052: child pid 25952 exit //signal Aborted (6)

しかし、代わりに $stmt2=$dbh->prepare("UPDATE ...."); を使用すると 奇妙なことは何も起こらず、ステートメントは問題なく実行されます。準備エミュレーションを有効にしても問題ありません。

$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES,true);

$stmt->closeCursor()最初のステートメントを実行した後に試してみましたが、 unset($stmt)(両方とも) 同じクラッシュが発生しました。PHP 5.4.7 を使用しています。なぜこれが起こるのですか?それはバグですか、それとも本当に奇妙な機能ですか?

[更新] xampp から OpenSUSE 12.3 デフォルトの Apache (2.2.22) および PHP (5.3.17) に切り替えても、同じエラーが発生しますが、より詳細なダンプ ログ: http://paste2.org/d0BtdOHI

[更新 2]サーバーとして MariaDB 5.5.29 の代わりに MySQL 5.5.27 を使用している場合にも発生することを確認したため、これは明らかに私のスクリプトから来ており、かなり普遍的です (念のため、centos 仮想マシンも試してみます)。これは私のディストリビューションの glibc 関連の問題です...)、さまざまなバージョンの apache、mysql、php で発生していますが、何が原因であるかの手がかりはまだありません...

[更新 3] CentOS 6.4 の方がはるかに優れているようで、問題なくスクリプトを実行できます。本番環境で使用しているので、心配する必要はないと思います。とにかく、ここで何が起こっているのか知りたいです...

4

1 に答える 1

3

この更新が遅れたことをお詫びしますが、PDO (Sybase) で同様の問題がありました。設定を解除したり、null に設定したりせずにステートメント変数を再利用することは絶対に避けるべきであることを確認できます。

PHP では、変数値を上書きするたびに、まず新しい変数を作成し、その後で古い値を置き換えて破棄します。ほとんどの場合、それは問題ではありませんが (1 つの変数を割り当てるために 2 倍のメモリを消費することを除けば)、ステートメントの場合はまったく異なります。ドライバーは、同じ PDO 接続内の複数のステートメントを適切に処理しません。

使用するドライバーによってはPDOStatement::closeCursor()、ステートメントを閉じない可能性があるため、問題は解決しません ( http://www.php.net/manual/en/pdostatement.closecursor.phpで、ドライバーに依存していることがわかります。ステートメントを閉じない PDO デフォルトを使用します)。

したがって、この場合、 のunset()間でPDO::prepare() すべての違いが生じます。

$stmt=$dbh->prepare("SELECT ....");   
$stmt->execute();
unset($stmt); // or $stmt = null; --> statement is destroyed at PDO
$stmt=$dbh->prepare("UPDATE ....");
于 2013-11-26T23:46:29.110 に答える