我们最近将 PHP 版本从 8.1.0 升级到了 8.3.10,发现查询失败时不再报告错误。
我们使用 PDO 类与 postgreSQL(版本 13.15)数据库进行交互,并将
ATTR_ERRMODE
设置为 ERRMODE_SILENT
,并使用 $statement->errorInfo()
来识别是否发生错误并检索任何相关信息。升级后,当查询失败时,我们仍然会收到标准的 success errorInfo()
成功响应(如下图)。使用 errorCode()
也会出现同样的问题。
将
ATTR_ERRMODE
更改为 ERRMODE_EXCEPTION
会提供错误信息,但需要对我们的代码库进行大量更改,而我们希望避免这种情况。
我测试了几个不同版本的PHP,发现这个问题是在PHP 8.1.8版本上引入的。此版本的 changelog 提到了对单键连接字符串的修复,但仅此而已。
我尝试过使用
errorCode()
来更改 php 版本,直接使用 PDO 类中的 errorInfo()
函数,而不是从 $statement
函数返回的 PDO::prepare()
var。我还尝试将用户名和密码传递到 PDO 声明中,而不是单个字符串。
在网上查找了一段时间后,我没有看到其他人报告此问题。
这是一些示例代码:
// Example connection string;
$dsn = "pgsql:host=$conn; port=$port; dbname=$dbName; user=$user; password=$pass";
// PDO
$pdo = new PDO($dsn, null, null, null);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
// Prepare a PDO Statement
$sqlQuery = "SELECT * FROM table WHERE incorrect_col = 1;";
$statement1 = $pdo->prepare($sqlQuery);
// Execute the PDO statement
$statement1->execute();
// Fetch all results in an indexed array.
$results = $statement1->fetchAll(PDO::FETCH_ASSOC);
$error = $statement1->errorInfo();
上面的示例代码生成下图:
有已知的解决方案吗?任何帮助将不胜感激。
感谢 ontrack 提出此解决方案。
从 PHP 8.1.8 开始,如果要检索错误信息,必须在触发execute()后立即调用errorInfo()。任何后续 PDO 操作(如 fetchAll())都将覆盖最后存储的错误。
这不完全是我想听到的,因为我们仍然需要重写很多代码,但至少有一个答案。