PDO не выбрасывает исключение из неправильного SQL-запроса

Я в значительной степени знаком с MySQLi и пытался PDO, я слышал, что это лучше. Я просматривал представленный здесь учебник. Они говорят, что PDO генерирует исключение, когда установлен PDO :: ERRMODE_EXCEPTION, и мы случайно делаем что-то неправильно с запросом (например, неверно набрав DELET вместо SELECT). Я набрал тот же неверный запрос, чтобы увидеть сообщение об ошибке и исключении в моей локальной среде. У меня есть последняя WAMP, установленная с PHP 5.5, MySQL 5.6 и Apache 2.4.9 на моем 32-разрядном ПК с Windows 7, но не получила того, чего ожидала, никаких исключений не было. Я попробовал тот же код, что и в учебнике:

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 не может генерировать исключения? У меня установлен драйвер PDO для MySQL.

Вероятно, это не так, потому что запрос никогда не выполняется и ожидает дальнейших инструкций.

Поскольку он показывает, что ничего не срабатывает , тогда все это действует в глазах PDO; это моя аналогия по этому поводу.

Выполните его, и вы увидите, что это вызовет исключение.

Либо выполнив его после подготовки, либо просто ->query() а не ->prepare() .

На самом деле это связано с другим атрибутом соединения PDO, которое вы еще не рассмотрели. И это PDO::ATTR_EMULATE_PREPARES

Если вы добавите этот атрибут и установите его в false он сообщит, что расширение PDO выдаст prepare к базе данных для планирования компиляции, оптимизации и планирования в момент, когда вы выдаете ->prepare() . Если вы оставите его не установленным, он примет значение по умолчанию true , которое сообщает расширению EMULATE компиляции. Другими словами, он будет ждать до тех пор, пока вы не выполните команду ->execute() перед компиляцией оператора и сообщения об ошибках.

PDO :: ATTR_EMULATE_PREPARES Включает или отключает эмуляцию подготовленных операторов. Некоторые драйверы не поддерживают родные подготовленные заявления или имеют ограниченную поддержку для них. Используйте этот параметр, чтобы заставить PDO либо всегда подражать подготовленным операторам (если TRUE), либо попытаться использовать собственные подготовленные операторы (если FALSE). Он всегда будет возвращаться к эмуляции подготовленного оператора, если драйвер не сможет успешно подготовить текущий запрос.

Поэтому запустите свой код с помощью этого дополнительного параметра Attribute и увидите разницу.

 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); } 

Теперь вы получите сообщение, и файл будет создан с сообщением об ошибке