PHP 7尝试 - 捕获:无法捕获“可捕获的致命错误”

时间:2017-01-21 00:08:00

标签: php try-catch

我正在玩try - catch阻止:

<?php
try {
    $str = "http://rejstrik-firem.kurzy.cz/73631604";
    $domOb = new DOMDocument();
    $html = $domOb->loadHTMLFile($str);
    $domOb->preserveWhiteSpace = false; 
    $container = $domOb->getElementById('ormaininfotab');   
    echo $container; // <========= this is intended error which I want catch
} 
catch (Exception $e) {
   echo "Exception" . $e->getMessage() . ". File: " . $e->getFile() . ", line: " . $e->getLine();
} 

catch (Error $e) {
   echo "Error" . $e->getMessage() . ". File: " . $e->getFile() . ", line: " . $e->getLine();
}
?>

我的结果是:

  

捕获致命错误:类DOMElement的对象不可能   在第8行的/var/www/html/cirkve_ares/test.php中转换为字符串

为什么第二次捕获不会捕获此错误?

3 个答案:

答案 0 :(得分:1)

作为user2782001 mentioned,这不是PHP开发人员眼中的错误。他们甚至指出,这些类型的错误应该被引用为可恢复的&#39;:

  

我们应该摆脱对#34; catchable&#34;的任何引用。致命错误(如果它们仍然存在)有利于&#34;可恢复的&#34;致命错误。使用&#34; catchable&#34;这里令人困惑,因为它们无法使用catch块捕获。

ErrorException manual page上有一个简洁的解决方法来转换那些&#34; catchable / recoverable&#34;错误到ErrorException。

<?php
function exception_error_handler($severity, $message, $file, $line) {
    if (!(error_reporting() & $severity)) {
        // This error code is not included in error_reporting
        return;
    }
    throw new ErrorException($message, 0, $severity, $file, $line);
}
set_error_handler("exception_error_handler");
?>

现在您可以通过以下方式捕获这些错误:

<?php
try {
    // Error code
} catch (Error $e) { // this will catch only Errors 
    echo $e->getMessage();
}
?>

try {
    // Error code
} catch (Throwable $t) { // this will catch both Errors and Exceptions
    echo $t->getMessage();
}
?>

答案 1 :(得分:0)

有人将此报告为PHP开发人员的错误,他们迅速认定这不是一个错误。 https://bugs.php.net/bug.php?id=72948&edit=3

  

此案例已被故意省略......(实际上,您可以使用错误处理程序将可恢复的致命错误转换为异常...)

所以你仍然需要使用

的set_error_han dler()

功能,我们都希望留下。 PHP的开发人员非常善于从不让你的一天太阳光......

答案 2 :(得分:0)

可能存在一些致命错误,甚至没有被set_error_handler()\Throwable捕获。

以下实现将捕获php 7.1中测试的\Throwable甚至未捕获的错误。它只能在开发环境中实现(只需将其添加到开发配置文件中),而不应在生产环境中完成。

  

实施

register_shutdown_function(function () {
    $err = error_get_last();
    if (! is_null($err)) {
        print 'Error#'.$err['message'].'<br>';
        print 'Line#'.$err['line'].'<br>';
        print 'File#'.$err['file'].'<br>';
    }
});
  

示例错误

Error# Class Path/To/MyService contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Path/To/MyServiceInterface::add)
Line# 12
File# Path/To/MyService.php