Поддерживать подготовленные операторы на стороне сервера с PDO?

Учитывая что-то вроде

DB()->prepare("SELECT * FROM mysql.general_log WHERE user_host LIKE ?");

$statement->execute( array('%console%') );

foreach($statement as $record){
    var_dump($record);
}

Содержимое general_log

*************************** 1. row ***************************
event_time: 2011-04-20 14:27:59
user_host: REDACTED[REDACTED] @ REDACTED [192.168.56.101]
thread_id: 30
server_id: 0
command_type: Connect
argument: REDACTED@REDACTED on REDACTED
*************************** 2. row ***************************
event_time: 2011-04-20 14:27:59
user_host: REDACTED[REDACTED] @ REDACTED [192.168.56.101]
thread_id: 30
server_id: 0
command_type: Query
argument: SELECT * FROM mysql.general_log WHERE user_host LIKE '%console%'

Я работаю внутри мерзкой структуры (без модульных тестов, без документации, без правил или причин), поэтому возможно ли, что где-то кто-то явно отключил подготовленные операторы MySQL, заставляющие PDO использовать эмулируемый режим... или это ожидаемое поведение?

PHP — это драйвер PHP Version 5.2.10-2ubuntu6 PDO для MySQL, версия клиентской библиотеки 5.1.41.

Обновление: PDO() построен со следующими атрибутами

PDO::ATTR_PERSISTENT => false
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true

Я просмотрел документацию PDO, но, к сожалению, там не упоминается флаг, подобный тому, о котором написано в этот похожий вопрос


person David    schedule 20.04.2011    source источник
comment
Может быть, я что-то упустил, но вы, кажется, забыли сказать нам, что на самом деле идет не так. Если вас беспокоит режим эмуляции, проверьте PDO::ATTR_EMULATE_PREPARES — он хорошо спрятан.   -  person Charles    schedule 22.04.2011
comment
Приношу свои извинения, проблема в том, что PDO на самом деле не вызывает MySQL и не готовит оператор, он, кажется, автоматически использует режим эмуляции. Я убедился в этом, просматривая общий_лог моего сервера разработки и отслеживая связь через WireShark.   -  person David    schedule 22.04.2011
comment
@Charles, если вам нужны очки, добавьте PDO::ATR_EMULATE_PREPARES в качестве решения. Установите для него значение false, и теперь он использует подготовку на стороне MySQL/сервера поверх уровня эмуляции.   -  person David    schedule 22.04.2011
comment
Выпуск Wireshark — это хардкорное исследование, молодец! Я разместил атрибут в качестве ответа и добавил несколько важных примечаний, которые могут заставить вас пересмотреть решение об отключении эмуляции при определенных условиях.   -  person Charles    schedule 22.04.2011
comment
@Charles, strace и Wireshark - мои хорошие друзья ... они пригодятся в самых странных случаях, плюс я хотел быть абсолютно уверенным, что MySQL не получил указание подготовить операторы.   -  person David    schedule 22.04.2011


Ответы (2)


Некоторые драйверы PDO не поддерживают собственные подготовленные операторы, поэтому PDO выполняет эмуляцию подготовки. Это также позволяет вам вручную включить эту эмуляцию.

Проверьте атрибут PDO::ATTR_EMULATE_PREPARES. Это плохо документировано в текущем руководстве PDO. Под плохой документацией я подразумеваю, что она появляется только в комментариях на сайте, а не в самом руководстве.

Как правило, вы хотите использовать собственные подготовленные операторы, когда это возможно. В случае MySQL, если вы используете кеш запросов, вы можете фактически захотеть отключить собственные подготовленные операторы в PDO! Дополнительная информация содержится в руководстве по MySQL, но короткая версия заключается в том, что версии до 5.1.17 не запускают подготовленные операторы через кеш запросов, а последующие версии используют кеш запросов только при определенных (но общих) условиях.

(Некоторые люди рекомендуют полностью отключить кеш запросов. Использование большого кеша размеры могут серьезно повлиять на производительность.)

person Charles    schedule 22.04.2011
comment
Рад, что вы добавили эту последнюю строку, когда я надеваю шляпу администратора базы данных, первое, что я делаю, это отключаю кэш запросов. Обычно есть куда лучше кинуть ОЗУ. - person David; 22.04.2011
comment
Кстати. Кэширование запросов в любом случае исчезло: кеширование запросов устарело, начиная с MySQL 5.7.20, и удалено в MySQL 8.0. dev.mysql.com/doc/refman/5.7/en/ запрос-кэш.html - person mikep; 07.01.2019

По умолчанию PDO_MYSQL эмулирует подготовленные операторы. Чтобы использовать собственные подготовленные операторы на стороне сервера, необходимо явно установить

$PDO->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
person Grigori Kochanov    schedule 30.05.2011