在使用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错误时,我可以看到查询文本