В PHP с PDO, как проверить окончательный SQL параметризованный запрос? [дубликат]
этот вопрос уже есть ответ здесь:
- Получение необработанной строки SQL-запроса из подготовленных инструкций PDO 14 ответов
в PHP, при доступе к базе данных MySQL с PDO с параметризованным запросом, Как вы можете проверить окончательный запрос (после замены всех токенов)?
есть ли способ проверить, что реально исполняются по базе данных?
9 ответов:
поэтому я думаю, что наконец-то отвечу на свой собственный вопрос, чтобы иметь полное решение для записи. Но нужно поблагодарить Бена Джеймса и Кайлаша Баду, которые предоставили подсказки для этого.
Короткий Ответ:
как упоминал Бен Джеймс:нет.
полный SQL-запрос не существует на стороне PHP, потому что запрос с токенами и параметры отправляются отдельно в базу данных. Только на стороне базы данных полный запрос существует.даже попытка создать функцию для замены токенов на стороне PHP не гарантирует, что процесс замены будет таким же, как и SQL (хитрые вещи, такие как token-type, bindValue vs bindParam,...)
решение
здесь я подробно остановлюсь на ответе Кайлаша Баду. Регистрируя все SQL-запросы, мы можем видеть, что действительно выполняется на сервере. С mySQL это можно сделать, обновив my.КНФ (или мои.ini в моем случае с WAMP server), и добавление строки типа:log=[REPLACE_BY_PATH]/[REPLACE_BY_FILE_NAME]
просто не запускайте это в производство!!!
использование подготовленных операторов с параметризованными значениями-это не просто еще один способ динамического создания строки SQL. Вы создаете подготовленный оператор в базе данных, а затем отправляете только значения параметров.
так что, вероятно, отправлено в базу данных будет
PREPARE ...
, потомSET ...
и наконецEXECUTE ...
.вы не сможете получить некоторые строки SQL, как
SELECT * FROM ...
, даже если это приведет к эквивалентным результатам, потому что такой запрос никогда не был отправлен база данных.
вы могли бы использовать
PDOStatement->debugDumpParams
. Смотрите документация PHP .
Я проверяю журнал запросов, чтобы увидеть точный запрос, который был выполнен как подготовленный оператор.
Я изначально избегал включения регистрации для мониторинга PDO, потому что я думал, что это будет хлопот, но это совсем не сложно. Вам не нужно перезагружать MySQL (после 5.1.9):
выполните этот SQL в phpMyAdmin или любой другой среде, где у вас могут быть высокие привилегии БД:
SET GLOBAL general_log = 'ON';
в терминале, хвост ваш файл журнала. Мой был здесь:
>sudo tail -f /usr/local/mysql/data/myMacComputerName.log
вы можете искать свои файлы mysql с помощью этой команды терминала:
>ps auxww|grep [m]ysqld
я нашел что PDO избегает всего, так что вы не можете написать
$dynamicField = 'userName'; $sql = "SELECT * FROM `example` WHERE `:field` = :value"; $this->statement = $this->db->prepare($sql); $this->statement->bindValue(':field', $dynamicField); $this->statement->bindValue(':value', 'mick'); $this->statement->execute();
потому что он создает:
SELECT * FROM `example` WHERE `'userName'` = 'mick' ;
который не создал ошибку, просто пустой результат. Вместо этого мне нужно было использовать
$sql = "SELECT * FROM `example` WHERE `$dynamicField` = :value";
и
SELECT * FROM `example` WHERE `userName` = 'mick' ;
когда вы закончите выполнять:
SET GLOBAL general_log = 'OFF';
иначе ваши журналы будут огромные.
то, что я сделал, чтобы напечатать этот фактический запрос, немного сложно, но он работает :)
в методе, который назначает переменные для моего оператора у меня есть еще одна переменная, которая выглядит немного так:
$this->fullStmt = str_replace($column, '\'' . str_replace('\'', '\\'', $param) . '\'', $this->fullStmt);
где:
$column
мой маркер$param
фактическое значение присваивается token$this->fullStmt
- Это моя печать только заявление при замене лексемычто он делает, это просто заменить токены со значениями, когда реальное назначение PDO происходит.
надеюсь, я вас не смутил и хотя бы указал вам верное направление.
самый простой способ это сделать-это прочитать файл журнала выполнения mysql, и вы можете сделать это во время выполнения.
здесь есть хорошее объяснение: