2016-01-26 74 views
5

我對MySQLi非常熟悉,並且正在嘗試PDO,我聽說它更好。我正在閱讀教程目前here。他們說PDO在設置PDO :: ERRMODE_EXCEPTION時拋出一個異常,並且我們意外地在查詢時發生了錯誤(例如,輸入錯誤,DELECT而不是SELECT)。我輸入了相同的錯誤查詢以查看本地環境中的錯誤和異常消息。我在32位Windows 7個人電腦上安裝了最新的WAMP,安裝了PHP 5.5,MySQL 5.6和Apache 2.4.9,但沒有得到我期待的結果,沒有發生任何異常。我嘗試了教程中發佈的相同代碼:PDO不會在錯誤的SQL查詢上拋出異常

try { 
$DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); 
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

# UH-OH! Typed DELECT instead of SELECT! 
$DBH->prepare('DELECT name FROM people'); 
} 
catch(PDOException $e) { 
echo "I'm sorry, Dave. I'm afraid I can't do that."; 
file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND); 
} 

沒有PDOError.txt,沒有錯誤消息。教程或我的環境有問題嗎?或者有些情況下PDO無法拋出異常?我有爲MySQL安裝的PDO驅動程序。

+3

它可能失敗,因爲該查詢永遠不會被執行,正在等待進一步的指示。執行它並查看它是否拋出異常。 –

+0

$ DBH-> query('DELECT name FROM people');將執行查詢 –

+0

猜猜弗雷德,你是絕對正確的。執行它的工作。非常感謝。 –

回答

5

這可能是失敗的,因爲查詢永遠得不到執行並且正在等待進一步的指示。

既然它認爲沒有什麼觸發,那麼它在PDO的眼中都是有效的;這是我的比喻。

執行它,你會看到它會拋出一個異常。

可以在準備之後執行它,或者通過簡單的​​而不是->prepare()執行。

+0

再次感謝... –

+0

@Devashish你非常歡迎,*歡呼* –

5

這實際上是與您可能尚未考慮的PDO連接的另一個屬性有關。這是PDO::ATTR_EMULATE_PREPARES

如果添加此屬性,並將其設置爲false它會告訴PDO擴展發出prepare到數據庫進行編譯,優化和執行規劃,在點你發出->prepare()。如果不保留它,則默認爲true,該值指示擴展模擬編譯。換句話說,它會等到您發出->execute()之後纔會編譯語句並報告錯誤。

PDO :: ATTR_EMULATE_PREPARES啓用或禁用模擬預準備語句。某些驅動程序不支持本地準備的語句或對它們提供有限的支持。使用此設置可強制PDO始終模擬預準備語句(如果爲TRUE),或嘗試使用原生準備語句(如果爲FALSE)。如果驅動程序無法成功準備當前查詢,它總是會回退到模擬準備好的語句。

因此,使用這個額外的屬性設置來運行你的代碼,並查看其差異。

try { 
    $DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass); 
    $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    $DBH->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE); 

    # UH-OH! Typed DELECT instead of SELECT! 
    $DBH->prepare('DELECT name FROM people'); 
} 
catch(PDOException $e) { 
    echo "I'm sorry, Dave. I'm afraid I can't do that."; 
    file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND); 
} 

現在你會得到的消息和文件將創建包含錯誤消息

+0

一點也不像一個團隊的努力搞清楚這些事情,*呵呵斯莫基?* ;-) –

+0

@弗雷德-II-疑難雜症回來的人,你有我的嗎?你有課程! – RiggsFolly

+0

所有時間Smokey ;-) –