Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

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

Нет никакого "построения" SQL-запроса на стороне PHP, поэтому нет способа получить этот запрос.

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

Ответ 2

Для подготовленных операторов, которые выполняются с функциями mysql_stmt_prepare() и mysql_stmt_execute() C, сервер записывает строки Prepare и Execute в общий журнал запросов, чтобы вы могли сказать, когда инструкции подготовлены и выполнены.
[...] сервер записывает следующие строки в общий журнал запросов:
Подготовьте [1] ВЫБОР?
Выполнить [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";

Ответ 3

Я обычно делаю это, когда мне нужно отладить подготовленный 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 будет интерпретировать все как одну строку, принимая каждый параметр как помещающий его на каждый замененный %s.

Ответ 4

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

Ответ 5

Недавно я обновил этот проект, включив интеграцию композитора, модульное тестирование и улучшив обработку принимаемых аргументов по ссылке (для этого требуется обновление до 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 = '[email protected]'

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

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

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

Ответ 6

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