В PHP с PDO, как проверить окончательный SQL параметризованный запрос? [дубликат]


этот вопрос уже есть ответ здесь:

  • Получение необработанной строки SQL-запроса из подготовленных инструкций PDO 14 ответов

в PHP, при доступе к базе данных MySQL с PDO с параметризованным запросом, Как вы можете проверить окончательный запрос (после замены всех токенов)?

есть ли способ проверить, что реально исполняются по базе данных?

9 125

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, и вы можете сделать это во время выполнения.

здесь есть хорошее объяснение:

как показать последние запросы, выполненные на MySQL?

Я не верю, что вы можете, хотя я надеюсь, что кто-то докажет мне неправоту.

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

Я думаю, что самый простой способ увидеть окончательный текст запроса при использовании pdo-это сделать специальную ошибку и посмотреть сообщение об ошибке. Я не знаю, как это сделать, но когда я делаю ошибку sql в Yii framework, которые используют pdo, я мог видеть текст запроса