如何调试PDO数据库查询?

2022-08-30 06:49:00

在迁移到 PDO 之前,我通过连接字符串在 PHP 中创建 SQL 查询。如果我遇到数据库语法错误,我可以回显最终的SQL查询字符串,在数据库上自己尝试,并调整它,直到我修复了错误,然后将其放回代码中。

准备好的 PDO 语句更快、更好、更安全,但有一件事困扰着我:我从来没见过发送到数据库的最终查询。当我在Apache日志或自定义日志文件中收到有关语法的错误时(我在块内记录错误),我看不到导致它们的查询。catch

有没有办法捕获PDO发送到数据库的完整SQL查询并将其记录到文件中?


答案 1

你这样说:

我从看不到最终查询,因为它被发送到数据库

好吧,实际上,当使用预准备语句时,没有“最终查询”这样的东西

  • 首先,将语句发送到数据库,并在那里准备
    • 数据库分析查询,并构建查询的内部表示形式
  • 而且,当您绑定变量并执行语句时,只有变量被发送到数据库
    • 数据库将值“注入”到语句的内部表示形式中


所以,要回答你的问题:

有没有办法捕获PDO发送到数据库的完整SQL查询并将其记录到文件中?

否:由于任何地方都没有“完整的SQL查询”,因此无法捕获它。


出于调试目的,您可以做的最好的事情是通过将值注入到语句的SQL字符串中来“重新构造”“真正的”SQL查询。

在这种情况下,我通常做的是:

  • 使用占位符回显与语句对应的 SQL 代码
  • 并在紧接着使用(或等效项)来显示参数的值var_dump
  • 这通常足以看到可能的错误,即使您没有任何可以执行的“真实”查询。

在调试方面,这并不是很好 - 但这是预准备语句的代价以及它们带来的优势。


答案 2

在数据库日志中查找

尽管Pascal MARTIN是正确的,PDO不会一次将完整的查询全部发送到数据库,但ryeguy建议使用DB的日志记录功能实际上允许我看到完整的查询是由数据库组装和执行的。

操作方法如下:(这些说明适用于Windows计算机上的MySQL - 您的里程可能会有所不同)

  • 在 节中的 节中,添加一个命令,如my.ini[mysqld]loglog="C:\Program Files\MySQL\MySQL Server 5.1\data\mysql.log"
  • 重新启动 MySQL。
  • 它将开始记录该文件中的每个查询。

该文件将快速增长,因此请务必将其删除,并在完成测试后关闭日志记录。


推荐