我正在学习在PHP中使用mysqli的预处理语句,通常,如果我在查询中遇到问题,我会首先将其echo到屏幕上以查看它的样子。
如何在预处理语句中执行此操作?
我想在变量被替换后查看SQL语句。
使用预处理语句:
在PHP端没有"构建"SQL查询的过程,因此实际上无法获取该查询。
这意味着如果您想查看SQL查询,则必须使用SQL查询,而不是预处理语句。
对于使用mysql_stmt_prepare()和mysql_stmt_execute() C API函数执行的准备语句,服务器会将Prepare和Execute行写入常规查询日志中,以便您可以确定语句何时被准备和执行。
[...] 服务器会将以下行写入常规查询日志:
Prepare [1] SELECT ?
Execute [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";
当我需要调试带参数的预处理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
上。
...
)来使这更容易。 - kurdtpage我最近更新了这个项目,加入了composer集成、单元测试以及更好地处理引用参数的接受(这需要升级到php 5.6)。
mysqli
和mysqli_stmt
类,以允许您查看潜在查询字符串的演示版本,这应该可以提供您所需的内容。
https://github.com/noahheck/E_mysqli
这是一个几乎可以直接替换普通mysqli
对象的替代品,当您使用prepare()
查询字符串时,它会返回一个自定义的mysqli_stmt
对象。绑定参数后,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扩展的实际经验,这个项目是应其姐妹项目用户的要求创建的,因此,任何使用该扩展的开发人员能提供的反馈将不胜感激。
免责声明 - 如我所说,我制作了该扩展。
var_dump()
或记录每个插入语句的变量,这样你就可以找出是错误数据还是逻辑上错误的 SQL 语句。你可以使用像Lottip这样的工具。其思路类似于MySQL代理。它解析MySQL数据包,提取查询及其参数,因此您可以查看准备好的语句及其内容。
var_dump
应该已经帮助您看到发送到 MySQL 服务器的数据了。 - Pascal MARTINmysqlnd
不可用时失去功能(例如get_result()
)等问题,似乎只为了SELECTs而值得。 - SteveCinq