Как просмотреть содержимое подготовленного заявления?

Я работаю над обучением использованию подготовленных операторов с mysqli в PHP и, как правило, если у меня возникла проблема с запросом, я просто повторяю его на экране, чтобы увидеть, как он выглядит как первый шаг.

Как я могу сделать это с помощью подготовленного заявления?

Я бы хотел увидеть инструкцию SQL после замены переменных.

Используя подготовленные заявления:

  • Когда вы готовите заявление, оно отправляется на сервер MySQL
  • Когда вы связываете переменные + выполняете оператор, только переменные отправляются на сервер MySQL
  • А оператор + связанные переменные выполняются на сервере MySQL – без повторного выполнения «подготовки» каждый раз, когда выполняется оператор (поэтому подготовленные операторы могут быть полезны для производительности, когда один и тот же оператор выполняется несколько раз)

Не существует «построения» SQL-запроса на стороне PHP, поэтому нет способа получить этот запрос.

Это означает, что если вы хотите увидеть SQL-запрос, вы должны использовать SQL-запросы, а не подготовленные операторы.

  • Вы можете использовать PDOStatement-> debugDumpParams, чтобы получить некоторую информацию о подготовленном заявлении (в случае, если вы используете pdo ).
  • Подготовленные утверждения регистрируются в общем журнале MySQL :

Для подготовленных операторов, выполняемых с помощью функций API mysql_stmt_prepare () и mysql_stmt_execute () C, сервер записывает строки Prepare и Execute в общий журнал запросов, чтобы вы могли сказать, когда инструкции подготовлены и выполнены.
[…] сервер записывает следующие строки в общий журнал запросов:
Подготовьте [1] SELECT?
Выполнить [1] ВЫБОР 3

Поэтому для целей отладки активируйте общий журнал и следите за этим файлом.

edit: oh, у вопроса есть тег [mysqli] … полностью игнорируется.
Если оператор не выполняется вообще, у вас (двойной / триплексный) проверено, что на этом пути не было ошибок?

 echo "<pre>Debug: start</pre>\n"; $mysqli = new mysqli('localhost', 'localonly', 'localonly', 'test'); if ($mysqli->connect_error) { die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error); } $result = $mysqli->query('CREATE TEMPORARY TABLE foo (id int auto_increment, x int, primary key(id))'); if ( false=== $result) { die('error : '. $mysqli->error); } $stmt = $mysqli->prepare('INSERT INTO foo (x) VALUES (?)'); if ( false===$stmt ) { die ('prepare() failed: ' . $mysqli->error); } $result = $stmt->bind_param('i', $x); if ( false===$result ) { die('bind_param() failed'); } $x = 1; $result = $stmt->execute(); if ( false===$result ) { die('execute() failed: '.$stmt->error); } echo "<pre>Debug: end</pre>\n"; 

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

Пример подготовки и выполнения:

 $sql = "SELECT VAL1, VAL2 FROM TABLE(?, '?', '?', '?', '?', ?, '?', '?', '?')"; $prep = ibase_prepare( $sql ) or die("Error"); $query = ibase_execute($prep, $param1, $param2, .....) or $err = true; ^^^^^^^^^^^^^^^^^^^^^^^ 

Легкий способ отладки полученного SQL предложения:

 printf( str_replace('?', '%s', $sql), $param1, $param2, ....); ^^^^^^^^^^^^^^^^^^^^^^ 

Вам нужно только сделать один printf с заменой? на подготовленном SQL одним% s printf будет интерпретироваться как строка и скопировать все параметры, переданные команде execute, в команду завершения sprintf.

Соглашаясь с Pascal MARTIN (+1), я предлагаю другой метод для отладки: var_dump() или регистрировать каждую переменную, которую вы вставляете в оператор, таким образом вы должны быть в состоянии выяснить, являются ли они неправильными данными или логически неправильным SQL.

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


Я создал набор классов, которые расширяют классы mysqli по умолчанию и mysqli_stmt чтобы вы могли просматривать представление потенциальной строки запроса, которая должна обеспечивать то, что вы ищете:

https://github.com/noahheck/E_mysqli

Это замена (близкая к) замены для обычного объекта mysqli который возвращает пользовательский объект mysqli_stmt при prepare() строки запроса. После привязки ваших параметров E_mysqli позволит вам просмотреть результирующую строку запроса как новое свойство объекта stmt :

 $mysqli = new E_mysqli($dbHost, $dbUser, $dbPass, $dbName); $query = "INSERT INTO registration SET name = ?, email = ?"; $stmt = $mysqli->prepare($query); $stmt->bind_param("ss", $_POST['name'], $_POST['email']); $stmt->execute(); echo $stmt->fullQuery; 

приведет к:

 INSERT INTO registration SET name = 'John Doe', email = 'john.doe@example.com' 

Есть несколько предостережений с использованием этого расширения (объяснено в README в проекте github), но для устранения неполадок проблемных областей вашего приложения или перехода к объектно-ориентированному стилю из процедурного, это должно обеспечить уровень помощи для большинства пользователей.

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

Отказ от ответственности. Как я уже сказал, я сделал это расширение.

Вы можете использовать инструмент Lottip . Идея действует как прокси-сервер MySQL. Он анализирует пакеты MySQL, извлекает запрос и его параметры, чтобы вы могли видеть подготовленные заявления с его содержимым.