我正在学习在PHP中使用带有mysqli的预处理语句,通常,如果我遇到查询问题,我只需将它回显到屏幕上,看看它的第一步是什么。
如何用准备好的声明做到这一点?
我希望在替换变量后看到SQL语句。
答案 0 :(得分:19)
使用准备好的陈述:
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)。
我已经创建了一组扩展默认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'
使用这个扩展有一些注意事项(在github项目的README中有解释),但是为了解决应用程序的麻烦区域,或者从过程转换到面向对象的样式,这应该为大多数提供一定程度的帮助用户。
正如我在github项目中概述的那样,我没有使用mysqli
扩展的任何实际经验,而且这个项目是应用户的要求创建的。姊妹项目,所以任何反馈都可以由开发人员在生产中使用它提供,我们将非常感激。
免责声明 - 正如我所说,我做了这个扩展。
答案 5 :(得分:0)
您可以使用Lottip之类的工具。这个想法就像MySQL代理一样。它解析MySQL数据包,提取查询及其参数,以便您可以查看包含其内容的预处理语句。