Intereting Posts
Как установить ширину + высоту для загруженного изображения PHP Клавиши сканирования сканирования Redis Скрыть цены на товары и кнопки «добавить в корзину», но не изменения для незарегистрированных пользователей в WooCommerce Тест Smarty, кто-нибудь? PHP sleep () вызывает высокую загрузку процессора xPath не находит ничего, кроме * Как реализовать красноречивые события в laravel с использованием commmon Trait для всех моделей Как обработать XML с PHP, который был отправлен на сервер как text / xml? Печать вывода отладки на консоль в Codeception В PHP объедините дублирующийся набор элементов многомерного массива и суммируйте значения определенного ключа CakePHP не будет применять группу по условию PHP: fopen: нет такого файла или каталога Функция незаписанного сдвига вправо не работает для отрицательного входа искаженный JSON с PHP Запрос MySQL возвращает нежелательные строки при извлечении строк на основе конкретных комбинаций тегов

В PHP с PDO, как проверить окончательный SQL-запрос с параметризацией?

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

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

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

Короткий ответ
Как упоминал Бен Джеймс: нет .
Полный SQL-запрос не существует на стороне PHP, поскольку запрос-с-токенами и параметры отправляются отдельно в базу данных. Только на стороне базы данных существует полный запрос.

Даже попытка создать функцию для замены токенов на стороне PHP не гарантирует, что процесс замены будет таким же, как SQL-код (сложный материал, такой как токен-тип, bindValue vs bindParam, …)

Временное решение
Здесь я подробно опишу ответ Кайлаша Баду. Регистрируя все SQL-запросы, мы можем видеть, что действительно выполняется на сервере. С mySQL это можно сделать, обновив my.cnf (или my.ini в моем случае с Wamp-сервером) и добавив строку, такую ​​как:

 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 или в любой другой среде, где у вас могут быть высокие привилегии db:

 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 – это фактическое значение, присвоенное токену
$this->fullStmt – это мой оператор только для печати с замененными токенами

То, что он делает, это просто заменить токены значениями, когда происходит реальное назначение PDO.

Надеюсь, я не смутил вас и, по крайней мере, указал вам в правильном направлении.

Самый простой способ сделать это – прочитать файл журнала выполнения mysql, и вы можете это сделать во время выполнения.

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

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

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

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

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