【问题标题】:Why PDO Exception Error Not Caught?为什么没有捕获到 PDO 异常错误?
【发布时间】:2012-01-01 01:52:14
【问题描述】:

我有一个 PHP 脚本,在 SQL 查询语句中有两个故意的拼写错误:

try
{
 $stmt = $dbh->prepare("SELECT COUNT(*) FROM Product WHERE non-existent_column=?");
 $stmt->blindValue(1, $id, PDO::PARAM_INT);
 $stmt->execute();
 $row = $stmt->fetchColumn();
}
catch(PDOException $err)
{
 var_dump($err->getMessage());
 var_dump($dbh->errorInfo());
}

但是,即使将属性设置为PDO::ERRMODE_EXCEPTION,脚本也不会捕获错误。我在这里错过了什么?

更新:

这是完整的脚本。第二个错字blindValue 已恢复。错误仍未被发现:

<?php

$user= "user";
$password = "password";
$dsn = "mysql:dbname=Catalogue;host=localhost";
$dbh = new PDO($dsn, $user, $password);
$dbh->setAttribute(PDO::ERRMODE_EXCEPTION); 
$id = 1000;

try
{
 $stmt = $dbh->prepare("SELECT COUNT(*) FROM Product WHERE non-existent_column=?");
 $stmt->bindValue(1, $id, PDO::PARAM_INT);
 $stmt->execute();
 $row = $stmt->fetchColumn();
}
catch(PDOException $err)
{
 echo "caught";
 var_dump($err->getMessage());
 var_dump($dbh->errorInfo());
 exit();
}

var_dump($stmt);
var_dump($row);
echo "uncaught";
exit();

?>

【问题讨论】:

  • 如果异常以默认错误处理程序结束,你能显示消息吗?你也确实在-&gt;blindValue 中有错字。这将导致致命错误,而不是异常。
  • @mario,您的意思是上面添加的$err 中的默认值?我也加了一个,没有错误信息。脚本会跳过整个 catch 块。
  • @mario,是的,这是第二个错字。第一个是不存在的列。
  • 如果您确实收到错误消息PHP Fatal error: Call to undefined method PDOStatement::blindValue(),则无法通过try/catch 声明捕获。这不是例外,是解释器错误。
  • @mario,我明白了.. 但是即使我纠正了第二个错误,也无法捕获第一个错误。

标签: php mysql pdo error-handling


【解决方案1】:

您对 setAttribute() 的调用缺少第一个参数:

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

如果你没有得到一个

Warning: PDO::setAttribute() expects exactly 2 parameters, 1 given

您的error_reporting level 对于开发服务器来说太低了和/或您没有关注the error log 或没有设置display_errors=On(您喜欢哪个;我更喜欢错误日志而不是display_errors) .


编辑:请尝试

<?php
echo 'php version: ', phpversion(), "\n";

try {
    $dbh = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');  
    echo 'client version: ', $dbh->getAttribute(PDO::ATTR_CLIENT_VERSION), "\n";
    echo 'server version: ', $dbh->getAttribute(PDO::ATTR_SERVER_VERSION), "\n";
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
catch(PDOException $err) {
    var_dump($err->getMessage());
    die('...');
}

$id = 'foo';

try
{
    $stmt = $dbh->prepare("SELECT COUNT(*) FROM Product WHERE `non-existent_column`=?");
    $stmt->bindValue(1, $id, PDO::PARAM_INT);
    $stmt->execute();
    $row = $stmt->fetchColumn();
}
catch(PDOException $err)
{
    var_dump($err->getMessage());
    var_dump($dbh->errorInfo());
    die('....');
}

echo 'done.';

打印在我的机器上

php version: 5.3.5
client version: mysqlnd 5.0.7-dev - 091210 - $Revision: 304625 $
server version: 5.5.8
string(94) "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'non-existent_column' in 'where clause'"
array(3) {
  [0]=>
  string(5) "42S22"
  [1]=>
  int(1054)
  [2]=>
  string(54) "Unknown column 'non-existent_column' in 'where clause'"
}
....

【讨论】:

  • 在我的机器上也可以正常工作。这是正确的答案,因为(强制时)不会捕获异常的唯一原因是 PDO 未处于异常模式。这正确地将其设置为异常模式,并且在我的副本上运行良好。 +1 以获得正确而详细的答案。
  • 它也适用于我。但是我找不到我的脚本哪里出错了。不管怎样,谢谢。我会进一步调查。
【解决方案2】:
$stmt->blindValue(1, $id, PDO::PARAM_INT);

这应该是$stmt-&gt;bindValue(1, $id, PDO::PARAM_INT);

您无法捕获 致命错误,例如调用未定义的函数/方法。

【讨论】:

  • @ThiefMaster,我已将blindValue 恢复为bindValue。错误仍未被发现:(
【解决方案3】:

我经历过,意识到这是我的 PHP 配置文件。

xdebug.show_exception_trace = 1

如果是这样,异常总是会出现。

【讨论】:

    猜你喜欢
    • 2012-03-03
    • 2011-11-28
    • 2022-01-06
    • 2016-06-08
    • 2012-08-14
    • 2017-06-18
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多