在PHP中使用PDO,如何检查最终的SQL参数化查询?

时间:2009-11-23 21:56:10

标签: php mysql pdo sql-parametrized-query

在PHP中,当使用带有参数化查询的PDO访问MySQL数据库时,如何检查最终查询(在替换所有令牌之后)?

有没有办法检查数据库真正执行的内容?

9 个答案:

答案 0 :(得分:53)

所以我想我最终会回答我自己的问题,以便为记录提供完整的解决方案。但不得不感谢Ben James和Kailash Badu为此提供了线索。

简答
如Ben James所述: NO
完整的SQL查询在PHP端不存在,因为带有forkens的查询和参数是分别发送到数据库的。 仅在数据库端存在完整查询。

即使尝试在PHP端创建替换令牌的函数也不能保证替换过程与SQL版本相同(令牌类型,bindValue和bindParam之类的棘手的东西,......)

解决方法
这是我详细阐述Kailash Badu的答案。 通过记录所有SQL查询,我们可以看到服务器上真正运行的是什么。 使用mySQL,可以通过更新my.cnf(或者我的Wamp服务器中的my.ini)并添加如下行来完成:

log=[REPLACE_BY_PATH]/[REPLACE_BY_FILE_NAME]

只是不要在生产中运行这个!!!

答案 1 :(得分:27)

将预准备语句与参数化值一起使用不仅仅是动态创建SQL字符串的另一种方法。您可以在数据库中创建预准备语句,然后单独发送参数值。

那么可能发送到数据库的是PREPARE ...,然后是SET ...,最后是EXECUTE ...

你将无法得到像SELECT * FROM ...这样的SQL字符串,即使它会产生相同的结果,因为实际上并没有将这样的查询发送到数据库。

答案 2 :(得分:26)

您可以使用PDOStatement->debugDumpParams。请参阅the PHP documentation

答案 3 :(得分:9)

我检查查询日志以查看作为预准备语句执行的确切查询。

答案 4 :(得分:5)

我最初避免开启日志来监控PDO,因为我认为这将是一个麻烦,但它并不难。您不需要重启MySQL(在5.1.9之后):

在phpMyAdmin或任何其他可能具有高数据库权限的环境中执行此SQL:

SET GLOBAL general_log = 'ON';

在终端中,拖尾日志文件。我在这里:

>sudo tail -f /usr/local/mysql/data/myMacComputerName.log

您可以使用以下终端命令搜索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';

或者你的日志会变得很大。

答案 5 :(得分:1)

我所做的打印实际查询有点复杂,但它有效:)

在为我的语句分配变量的方法中,我有另一个看起来像这样的变量:

$this->fullStmt = str_replace($column, '\'' . str_replace('\'', '\\\'', $param) . '\'', $this->fullStmt);

其中:
$column是我的代币 $param是分配给令牌的实际值 $this->fullStmt是我的仅打印声明,替换了令牌

它的作用是在真正的PDO分配发生时简单地用值替换标记。

我希望我没有混淆你,至少指出你正确的方向。

答案 6 :(得分:1)

最简单的方法是读取mysql执行日志文件,你可以在运行时完成。

这里有一个很好的解释:

How to show the last queries executed on MySQL?

答案 7 :(得分:0)

我不相信你可以,但我希望有人会证明我错了。

我知道你可以打印查询,它的toString方法会显示没有替换的sql。如果您正在构建复杂的查询字符串,这可能很方便,但它不会为您提供带有值的完整查询。

答案 8 :(得分:-1)

我认为在使用pdo时查看最终查询文本最简单的方法是发出特殊错误并查看错误消息。我不知道该怎么做,但是当我在使用pdo的yii框架中出现sql错误时,我可以看到查询文本