在使用PDO的PHP中,如何检查最终的SQL参数化查询?
在PHP中,当使用带有参数化查询的PDO访问MySQL数据库时,如何检查最终查询(replace所有令牌之后)?
有没有办法检查数据库真正执行的是什么?
所以我想我会最终回答我自己的问题,以便有一个完整的解决scheme的logging。 但是要感谢Ben James和Kailash Badu为此提供了线索。
简答
正如本詹姆斯所提到的: 没有 。
完整的SQL查询在PHP端不存在,因为带有令牌的查询和参数是分别发送到数据库的。 只有在数据库端存在完整的查询。
即使试图创build一个函数来replace在PHP端的令牌不会保证replace过程是一样的SQL一样(棘手的东西像令牌types,bindValue vs bindParam,…)
解决方法
我在这里详细解释凯拉什·巴杜的答案。 通过logging所有SQL查询,我们可以看到服务器上真正运行的是什么。 使用mySQL,可以通过更新my.cnf(或者在我的情况下使用Wamp服务器的my.ini)来完成,然后添加一行:
log=[REPLACE_BY_PATH]/[REPLACE_BY_FILE_NAME]
只是不要在生产中运行这个!
使用具有参数值的预准备语句不是简单地另一种dynamic创buildSQLstring的方法。 您在数据库中创build一个准备好的语句,然后单独发送参数值。
那么可能发送到数据库的将是一个PREPARE ...
,然后是SET ...
,最后是EXECUTE ...
你将无法像SELECT * FROM ...
那样得到一些SQLstring,即使它会产生相同的结果,因为没有这样的查询实际上被发送到数据库。
您可能可以使用PDOStatement->debugDumpParams
。 查看PHP文档 。
我检查查询日志以查看作为准备语句执行的确切查询。
我最初避免开启日志logging来监视PDO,因为我认为这将是一个麻烦,但它并不难。 您不需要重新启动MySQL(在5.1.9之后):
在phpMyAdmin或其他您可能具有高数据库权限的环境中执行此SQL:
SET GLOBAL general_log = 'ON';
在terminal中,尾巴你的日志文件。 我在这里:
>sudo tail -f /usr/local/mysql/data/myMacComputerName.log
你可以用这个terminal命令search你的mysql文件:
>ps auxww|grep [m]ysqld
我发现PDO逃脱了一切,所以你不能写
$dynamicField = 'userName'; $sql = "SELECT * FROM `example` WHERE `:field` = :value"; $this->statement = $this->db->prepare($sql); $this->statement->bindValue(':field', $dynamicField); $this->statement->bindValue(':value', 'mick'); $this->statement->execute();
因为它创造:
SELECT * FROM `example` WHERE `'userName'` = 'mick' ;
哪一个没有产生错误,只是一个空的结果。 相反,我需要使用
$sql = "SELECT * FROM `example` WHERE `$dynamicField` = :value";
要得到
SELECT * FROM `example` WHERE `userName` = 'mick' ;
当你完成执行时:
SET GLOBAL general_log = 'OFF';
否则你的日志会变得巨大。
我所做的打印实际查询有点复杂,但它的工作:)
在将variables赋值给我的语句的方法中,我有另一个variables,看起来有点像这样:
$this->fullStmt = str_replace($column, '\'' . str_replace('\'', '\\\'', $param) . '\'', $this->fullStmt);
哪里:
$column
是我的令牌
$param
是分配给令牌的实际值
$this->fullStmt
是我用打印语句replace的标记
它的作用是在真正的PDO分配发生时简单地用值replace标记。
我希望我不会混淆你,至less指出你正确的方向。
最简单的方法是通过阅读mysql执行日志文件,你可以在运行时做到这一点。
这里有一个很好的解释:
如何显示在MySQL上执行的最后一个查询?
我不相信你可以,但我希望有人能certificate我是错的。
我知道你可以打印查询和它的toString方法将显示你没有更换的SQL。 如果您构build复杂的查询string,这可能会很方便,但它不会为您提供具有值的完整查询。
我认为最简单的方法来查看最后的查询文本,当你使用pdo是做出特殊的错误,看看错误消息。 我不知道该怎么做,但是当我在使用pdo的yii框架中发生sql错误时,我可以看到查询文本