PHP:异常和可捕获的致命错误有啥区别?

Posted

技术标签:

【中文标题】PHP:异常和可捕获的致命错误有啥区别?【英文标题】:PHP: What is the difference between an exception and a catchable fatal error?PHP:异常和可捕获的致命错误有什么区别? 【发布时间】:2018-09-15 10:56:18 【问题描述】:

我对这些术语及其在 php 中的确切含义/处理有点困惑:

异常可以这样定义:

当方法中发生错误时,该方法会创建一个对象并 将其交给运行时系统。对象,称为异常 对象,包含有关错误的信息,包括其类型和 发生错误时程序的状态。创建一个 调用异常对象并将其交给运行时系统 抛出异常。

可以捕获和处理异常。

致命错误可以这样定义:

致命错误是严重错误 - 例如,实例化一个 不存在的类的对象,或调用不存在的函数。 这些错误会导致脚本立即终止,并且 PHP 的 默认行为是在它们发生时将它们显示给用户。

致命错误不一定能被捕获(它们不会抛出通常的异常),否则不会有更具体的可捕获的致命错误

但是,可捕获的致命错误与正常的异常有何不同?它的处理方式相同吗?可捕获的致命错误是否属于特定类型的异常?

【问题讨论】:

它由set_error_handler 处理。但是知道一些可捕获的致命错误现在是 php7 中的正常异常,您可以使用 try catch on。 docs.php.net/errorfunc.constantsE_RECOVERABLE_ERROR 【参考方案1】:

致命错误不一定会被捕获(它们通常不会抛出 例外)

在版本 7 之前,情况就是如此。用于阻止脚本死在其轨道上的致命错误。但是,从版本 7 开始,它们现在显示为可捕获的异常。这使您可以从相当重要的问题中优雅地恢复。

但是,可捕获的致命错误与普通错误有何不同? 例外?

它们都实现了 Throwable,但具有不同的锚类:

Throwable
    Error
        ParseError
        ...
    Exception
        RuntimeException
        ...

它的处理方式是一样的吗?

是的,你可以捕获它们,就像异常一样。

是一个可捕获的致命错误 特定类型的异常与否?

取决于你的语义。一个可捕获的致命错误是一个例外,但它不是Exception,如果你明白我的意思的话。你可以这样区分;

// "traditional" exceptions
try 
    throw new Foo();
 catch (Exception $e) 


// v7 catchable fatal errors
try 
    $not_an_object->not_a_method();
 catch (Error $e) 


// both
try  
 catch (Throwable $e) 

【讨论】:

谢谢好答案 - 只需澄清一点:PHP 7 中的所有致命错误都可以捕获吗?这样我什至可以捕捉到“允许的内存大小已用尽”错误? 我很确定不是所有的都可以捕捉到。来自原始 RFC:“有些错误很容易转换为异常,有些则更复杂。有些是不可能的,例如内存限制或执行时间限制错误。E_CORE_ERROR 类型无法转换为使用异常,因为它发生在启动期间(至少在正确使用的情况下)。将 E_COMPILE_ERROR 转换为异常还需要对编译器进行一些重大更改。"

以上是关于PHP:异常和可捕获的致命错误有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

PHP 致命错误:未捕获的异常“Symfony\Component\Yaml\Exception\ParseException”

PHP 异常处理 总出现致命错误 无法捕获异常

致命错误:未捕获的异常“PDOException”,带有消息“SQLSTATE [42000]:语法错误或访问冲突 PHP 和 PDO

parse-php-sdk 致命错误:未捕获的异常 'Parse\ParseException' 带有消息 'unauthorized'

致命错误:第 19 行的 C:\xampp\htdocs\register.php 中抛出未捕获的异常“PDOException”

如何捕获致命错误:PHP 中的最大执行时间超过了 30 秒