Работа метода параметризованного PDO

ПОЖАЛУЙСТА ПРОЧИТАЙТЕ ВОПРОС ВНИМАТЕЛЬНО. Это обычно не глупо "мой код не работает !!!" вопрос.

Когда я запускаю этот код с предполагаемой ошибкой

try { $sth = $dbh->prepare("SELECT id FROM users WHERE name INN(?,?) "); $sth->execute(array("I'm","d'Artagnan")); } catch (PDOException $e) { echo $e->getMessage(); } 

Я получаю это сообщение об ошибке

У вас есть ошибка в синтаксисе SQL … около 'INN (' I \ 'm', 'd \' Artagnan ')' в строке 1

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

  1. Где он получает такое знакомое строковое представление – цитируется и экранируется? Это делается специально для сообщения об ошибке или является частью фактического запроса?
  2. Как это работает в реальности? Заменяет ли это заполнитель данными или нет?
  3. Есть ли способ получить весь запрос, а не только его немного, для целей отладки?

Обновить

mysqli делает это так, как ожидалось: он вызывает ошибку, говорит near 'INN(?,?)'

    попробуйте добавить

     $dbh->setAttribute( PDO::ATTR_EMULATE_PREPARES, false ); 

    😉

    Я не уверен обо всех подробностях, но я постараюсь ответить.

    1. Котировка происходит на стороне базы данных. База данных ускользает и дезактивирует все значения (см. Bullet 2), которые она получает, чтобы она правильно интерпретировалась. В момент выдачи ошибки база данных (в данном случае MySQL) выводит запрос, который он пытался запустить. Это было бы не так полезно, если бы он только показал подготовленную часть.

    2. Нет, нет. Во время подготовки запрос скомпилируется на стороне сервера. Когда запрос выполняется со значениями, передаются только значения. Это почти то же самое, что напрямую вызвать PREPARE и EXECUTE в базе данных.

    3. Это зависит от базы данных, которую вы используете. Например, MySQL может регистрировать все запросы в файле журнала (для этого установите параметры my.cnf). Но вы также можете использовать debugDumpParams () на стороне PHP.

    Надеюсь, это было немного полезно.