如何查看准备好的声明的内容?

时间:2010-02-20 22:18:19

标签: php mysql mysqli

我正在学习在PHP中使用带有mysqli的预处理语句,通常,如果我遇到查询问题,我只需将它回显到屏幕上,看看它的第一步是什么。

如何用准备好的声明做到这一点?

我希望在替换变量后看到SQL语句。

6 个答案:

答案 0 :(得分:19)

使用准备好的陈述:

  • 准备语句时,会将其发送到MySQL服务器
  • 绑定变量+执行语句时,只将变量发送到MySQL服务器
  • 并且语句+绑定变量在MySQL服务器上执行 - 每次执行语句时都不会重新执行“准备”(这就是为什么预备语句在同一语句时可以有利于性能的原因被执行了几次)

PHP端没有“构建”SQL查询,因此,无法实际获取该查询。

这意味着如果您想查看SQL查询,则必须使用SQL查询,而不是预处理语句。

答案 1 :(得分:12)

对于使用mysql_stmt_prepare()和mysql_stmt_execute()C API函数执行的预准备语句,服务器将Prepare和Execute行写入常规查询日志,以便您可以判断语句的准备和执行时间。
[...]服务器将以下行写入常规查询日志:
准备[1] SELECT?
执行[1] SELECT 3

因此,出于调试目的,请激活general log并密切关注该文件。

编辑:哦,问题有一个[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";

答案 2 :(得分:2)

当我需要使用参数调试准备好的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将all解释为一个字符串,将每个参数放在每个替换的%s上。

答案 3 :(得分:0)

同意Pascal MARTIN(+1)所以我建议另一种调试技术:var_dump()或记录你在语句中插入的每个变量,这样你应该能够弄清楚它是否是错误的数据或逻辑错误的SQL。

答案 4 :(得分:0)

我最近更新了这个项目,包括作曲家集成,单元​​测试以及通过引用更好地处理接受参数(这需要更新到php 5.6)。


我已经创建了一组扩展默认mysqlimysqli_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'

使用这个扩展有一些注意事项(在github项目的README中有解释),但是为了解决应用程序的麻烦区域,或者从过程转换到面向对象的样式,这应该为大多数提供一定程度的帮助用户。

正如我在github项目中概述的那样,我没有使用mysqli扩展的任何实际经验,而且这个项目是应用户的要求创建的。姊妹项目,所以任何反馈都可以由开发人员在生产中使用它提供,我们将非常感激。

免责声明 - 正如我所说,我做了这个扩展。

答案 5 :(得分:0)

您可以使用Lottip之类的工具。这个想法就像MySQL代理一样。它解析MySQL数据包,提取查询及其参数,以便您可以查看包含其内容的预处理语句。