PHP尝试/捕获和致命错误

Plo*_*ppe 20 php try-catch fatal-error

我使用以下脚本使用PHP使用数据库:

try{
    $db = new PDO('mysql:host='.$host.';port='.$port.';dbname='.$db, $user, $pass, $options);
}
catch(Exception $e){
    $GLOBALS['errors'][] = $e;
}
Run Code Online (Sandbox Code Playgroud)

现在,我想使用此数据库句柄使用此代码执行请求:

try{
    $query = $db->prepare("INSERT INTO users (...) VALUES (...);");
    $query->execute(array(
        '...' => $...,
        '...' => $...
    ));
}
catch(Exception $e){
    $GLOBALS['errors'][] = $e;
}
Run Code Online (Sandbox Code Playgroud)

这是问题所在:

  • 当与DB的连接正常时,一切正常,
  • 当连接失败但我不使用数据库时,我有$GLOBALS['errors'][]数组,之后脚本仍在运行,
  • 当与DB的连接失败时,我收到以下致命错误:

注意:未定义的变量:第32行的C:\ xampp\htdocs [...]\test.php中的db

致命错误:在第32行的C:\ xampp\htdocs [...]\test.php中调用非对象的成员函数prepare()

注意:第32行是$query = $db->prepare(...)指令.

也就是说,脚本崩溃了,try/catch似乎没用.你知道为什么第二次尝试/捕获不起作用以及如何解决它?

谢谢您的帮助!

编辑:有一些非常好的回复.我已经验证了一个不是我想要做的,但这可能是最好的方法.

Exp*_*lls 29

try/ catchblocks仅适用于抛出的异常(throw ExceptionException必须调用的子类).使用try/ 您无法捕获致命错误catch.

如果你的数据库连接无法建立,我认为这是致命的,因为你可能需要你的数据库在页面上做任何有意义的事情.

PDO如果无法建立连接,将抛出异常.您$db尝试使用它调用方法时未定义您的特定问题,因此您获得了一个致命的空指针(类型).而不是通过跳if ($db == null)火圈的人所提出的建议,你应该只是修复您的代码,以确保$db当你需要它具有确保一个数据库连接的那么脆弱的办法是提供使用它的代码是始终定义.

如果你真的想"捕获"致命错误,请使用set_error_handler,但这仍然会阻止脚本执行致命错误.


小智 16

在PHP7中,我们现在可以使用try catch致命错误和简单的工作

try {
   do some thing evil
} catch (Error $e) {
   echo 'Now you can catch me!';
}
Run Code Online (Sandbox Code Playgroud)

但通常情况下,我们应该避免使用catch错误,因为它涉及错过属于程序员责任的代码:-)

  • 如果您愿意,可以像在 Java 中一样捕获两者: try { ... } catch (Exception | Error $e) { ... } (2认同)