我正在重用一个变量来存储两个不同的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)
Run Code Online (Sandbox Code Playgroud)
但如果相反我使用$ 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]我也确认在使用MySQL 5.5.27而不是MariaDB 5.5.29作为服务器时会发生这种情况,因此它绝对是从我的脚本中提交的并且几乎是通用的(为了以防万一,还要尝试使用centos虚拟机)这是我的发行版中的一些glibc相关问题...),发生了不同版本的apache,mysql和php,但仍然没有找到可能是什么原因的线索......
[更新3]好吧看起来CentOS 6.4对它来说更好了,让我运行我的脚本没有任何麻烦,因为它是我正在使用的生产,我想没有什么可担心的.无论如何,我真的想知道这里发生了什么......
我对这个迟来的更新表示歉意,但我在 PDO (Sybase) 中遇到了类似的问题,并且我可以确认,绝对应该避免在不取消设置或设置为 null 的情况下重新使用语句变量。
在 PHP 中,每当我们覆盖变量值时,它首先创建新变量,然后才替换并销毁旧值。在大多数情况下,这不是问题(除了花费双倍的内存来分配单个变量),但对于语句来说,情况完全不同,因为它在创建第二个语句时不会关闭第一个语句或游标,而某些数据库驱动程序不能很好地处理同一 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 ....");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
763 次 |
| 最近记录: |