2013-06-03 60 views
5

我重用一個變量來存儲兩個不同的PDO MySQL的語句:重用PDO聲明VAR崩潰過程

$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->準備(「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好得多,讓我可以毫無麻煩地運行我的腳本,因爲這就是我在製作中使用的東西,所以我覺得沒有什麼可擔心的。無論如何,我真的很想知道這裏發生了什麼...

+1

報告給PHP的人。任何可能導致C級無效指針錯誤的PHP代碼都是* MAJOR *錯誤,並且需要被壓扁。 –

+0

你在用什麼驅動程序?像,什麼樣的數據庫類型? MySQL的? – silkfire

+0

從最新的xampp發行版(這是32位的順便說一句),從OpenSUSE 12.4 x64和Apache 2.4.3的PHP 5.4.7開始的'mysqld Ver 5.5.29-MariaDB-log for x86_64(源代碼發行)' – NotGaeL

回答

3

我對這個晚期更新表示歉意,但我有一個與PDO(Sybase)類似的問題,並且我可以確認重新使用語句變量而不復位或設置爲零應該一定要避免。在PHP中,無論何時我們覆蓋一個變量值,它都會首先創建新變量,並且只有在它之後纔會替換並銷燬舊值。在大多數情況下,這不是一個問題(除了花費兩倍的內存來分配單個變量),但是對於語句來說它是完全不同的,因爲它不會在創建第二個語句或光標時關閉第一個語句或光標,而某些數據庫驅動程序不能很好地處理同一個PDO連接中的多個語句。

根據您使用的驅動程序,PDOStatement::closeCursor()可能不會關閉語句,因此問題仍然存在(在http://www.php.net/manual/en/pdostatement.closecursor.php我們可以看到它取決於驅動程序,否則它將使用PDO默認值,它不會關閉語句)。

因此,在這種情況下,PDO::prepare()之間的unset()使所有的差異:

$stmt=$dbh->prepare("SELECT ...."); 
$stmt->execute(); 
unset($stmt); // or $stmt = null; --> statement is destroyed at PDO 
$stmt=$dbh->prepare("UPDATE ...."); 
+1

我確實嘗試在重新分配它之前取消設置語句var,但它沒有幫助。唯一的解決方法是使用不同的解決方案。當時我不記得確切的設置,但是我認爲這個問題可能與我在OpenSUSE中使用的libc版本有關,因爲回溯顯示,因爲我無法在其他發行版中使用相同的apache重現該錯誤,PHP和MySQL版本,以及切換Apache,MySQL和PHP版本都無法解決該發行版的問題。 – NotGaeL