我假设您的意思是您想要最终的 SQL 查询,并将参数值插入其中。我知道这对于调试很有用,但这不是准备好的语句的工作方式。参数不会与客户端的准备语句组合,因此 PDO 永远不应访问与其参数组合的查询字符串。
当你执行prepare()时,SQL语句被发送到数据库服务器,而当你执行execute()时,参数被单独发送。 MySQL 的通用查询日志确实显示了执行()后插入值的最终 SQL。以下是我的一般查询日志的摘录。我从 mysql CLI 运行查询,而不是从 PDO 运行查询,但原理是相同的。
081016 16:51:28 2 Query prepare s1 from 'select * from foo where i = ?'
2 Prepare [2] select * from foo where i = ?
081016 16:51:39 2 Query set @a =1
081016 16:51:47 2 Query execute s1 using @a
2 Execute [2] select * from foo where i = 1
如果您设置 PDO 属性 PDO::ATTR_EMULATE_PREPARES,您也可以获得您想要的结果。在此模式下,PDO 将参数插入到 SQL 查询中,并在您执行()时发送整个查询。这不是真正准备好的查询。您可以通过在execute()之前将变量插入到SQL字符串中来规避准备好的查询的好处。
回复 @afilina 的评论:
不,文本 SQL 查询是not与执行过程中的参数结合起来。所以 PDO 没有什么可以向您展示的。
在内部,如果您使用 PDO::ATTR_EMULATE_PREPARES,PDO 会在准备和执行之前创建 SQL 查询的副本并在其中插入参数值。但 PDO 不会公开此修改后的 SQL 查询。
PDOStatement 对象有一个属性 $queryString,但这仅在 PDOStatement 的构造函数中设置,并且在使用参数重写查询时不会更新。
对于 PDO 来说,要求他们公开重写的查询是一个合理的功能请求。但即使这样也不会给你“完整”的查询,除非你使用 PDO::ATTR_EMULATE_PREPARES。
这就是为什么我展示了上面使用 MySQL 服务器的通用查询日志的解决方法,因为在这种情况下,即使是带有参数占位符的准备好的查询也会在服务器上重写,并将参数值回填到查询字符串中。但这仅在日志记录期间完成,而不是在查询执行期间完成。