В PHP, при доступе к базе данных MySQL с PDO с параметризованным запросом, как вы можете проверить окончательный запрос (после замены всех токенов)?
Есть ли способ проверить, что действительно выполняется в базе данных?
В 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, и вы можете сделать это во время выполнения.
Здесь есть приятное объяснение:
Я не верю, что вы можете, хотя я надеюсь, что кто-то докажет мне, что я неправ.
Я знаю, что вы можете распечатать запрос, и его метод toString покажет вам sql без замены. Это может быть удобно, если вы строите сложные строки запросов, но не дает вам полного запроса со значениями.
Я думаю, что самый простой способ увидеть окончательный текст запроса при использовании pdo - это сделать специальную ошибку и посмотреть сообщение об ошибке. Я не знаю, как это сделать, но когда я делаю ошибку sql в структуре yii, использующей pdo, я мог видеть текст запроса