PHP7下Error和Exception

Error 和 Exception 的异同

  • Exception 需要通过 throw new Exception 手动抛出
  • Error 可以在 PHP 脚本执行发生错误时自动触发,也可以通过 trigger_errors() 手动触发
  • 都实现了 Throwable 接口,可以通过 catch (Throwable $t) {...} 同时捕获 Error 和 Exception
  • 如果不捕获并处理 Exception,程序会终止,并报出 Fatal Error 错误,但捕获后程序可以继续执行
  • 用 catch (Error $e) { ... },或者通过注册错误处理函数( set_error_handler())来捕获 Error
  • 用 catch (Exception $e) { ... } 或者通过注册异常处理函数( set_exception_handler())来捕获 Exception
  • 用 catch (Throwable $e) { ... } 可以同时捕获 Exception 和 Error
<?php 
echo 1/0; 
echo 666; 
echo 1%0; 
echo 666;

PHP Warning: Division by zero in /code/main.php on line 3
INF666
PHP Fatal error: Uncaught DivisionByZeroError: Modulo by zero in /code/main.php:5

Throwable

用户定义的类无法实现 Throwable,所以用户只能抛出 Exception 或 Error 的实例。扩展 Throwable 的接口只能通过扩展 Exception 或 Error 的类来实现。

继承关系 7.3.0

Error
   ArithmeticError
       DivisionByZeroError
    AssertionError
    CompileError
       ParseError
    TypeError
       ArgumentCountError
Exception
    ClosedGeneratorException
    DOMException
    ErrorException
    IntlException
    JsonException
    LogicException
       BadFunctionCallException
          BadMethodCallException
       DomainException
       InvalidArgumentException
       LengthException
       OutOfRangeException
    PharException
    ReflectionException
    RuntimeException
       OutOfBoundsException
       OverflowException
       PDOException
       RangeException
       UnderflowException
       UnexpectedValueException
    SodiumException

接口

Throwable {
/* Methods */
abstract public getMessage ( ) : string
abstract public getCode ( ) : int
abstract public getFile ( ) : string
abstract public getLine ( ) : int
abstract public getTrace ( ) : array
abstract public getTraceAsString ( ) : string
abstract public getPrevious ( ) : Throwable
abstract public __toString ( ) : string
}

Error

从 PHP 7 开始,大多数错误(致命错误和可恢复错误)被作为 Error 异常抛出,从而可以捕获并处理,防止脚本终止执行。与任何其他 Exception 异常一样,可以使用 try / catch 块捕获 Error 对象。
从致命(fatal)和可恢复(recoverable)的错误中抛出的异常并没有继承 Exception,而是继承自 Error。

Error 的严重等级

Parse error > Fatal Error > Waning > Notice > Deprecated
错误名称 解释 可能的原因 程序是否中止 如何捕获错误 备注
Parse error 语法错误 代码解析失败 中断执行 PHP7 之后可以用 catch (Error $e) { ... } 捕获
Fatal Error 运行时错误 实例化不存在的类,调不存在的方法 中断执行 PHP7 之后可以用 catch (Error $e) { ... } 捕获 可以使用 register_shutdown_function() 函数设置一个在 PHP 中止前执行收尾工作的函数
Waning 警告 四则运算时出现非数字 继续执行 可以用 set_error_handler() 捕获
Notice 注意 变量或数组下标未定义 继续执行 可以用 set_error_handler() 捕获
Deprecated 使用了废弃函数 函数已经废弃 继续执行 可以用 set_error_handler() 捕获

Error 处理流程

  1. 先看看有没有匹配的 catch 块(注意是 Error 类型而不是 Exception 类型:catch (Error $e) { ... }),如果有则被第一个匹配的 try / catch 块所捕获。
  2. 如果没有没有匹配的 catch 块,则去调用异常处理函数(事先通过 set_error_handler() 注册)进行处理(仅用于 Deprecated、Notice、Waning 这三种级别)。
  3. 如果尚未注册异常处理函数,则按照传统方式处理:报告错误(Fatal Error 等)。

设置 PHP 配置文件来处理错误

设置报告错误的等级

如果未设置错误处理程序,则 PHP 将根据 php.ini 配置文件处理发生的任何错误。error_reporting 指令控制报告和忽略哪些错误。虽然也可以在运行时通过调用 error_reporting() 函数来控制,但强烈建议设置配置指令,因为在脚本开始执行之前也可能会发生一些错误。
在开发环境中,为了了解并解决 PHP 引发的问题,最好将 error_reporting 设置为 E_ALL 来记录所有的错误。生产环境中,可以将 error_reporting 设置为 E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED 来避免记录过多信息,但是在多数情况因为下 E_ALL 可以提供早期预警,记录潜在的问题,也可以用于生产环境。

显示错误或记录日志

发生错误时,PHP 可以采取两种措施,由另外两个 php.ini 指令设置:

  • display_errors:输出错误。生产环境中必须禁用,因为它可能包含机密信息(如数据库密码),但可用于开发环境,确保立即报告问题。
  • log_errors:记录错误日志。这会将任何错误记录到 error_log 定义的文件或 syslog 中。这在生产环境中非常有用,可以记录发生的错误,然后根据这些错误生成报告。

Exception

Exception 出现的原因

PHP 在使用异常机制之前,通过返回错误码来表示函数的执行结果。部分函数返回 TRUE 或 FALSE,部分函数返回 0 或 1、-1。难以统一且无法包含足够的报错原因等信息。例如 strtotime() 函数,成功则返回时间戳,否则返回 FALSE,但是在 PHP 5.1.0 之前本函数在失败时返回 -1。
异常机制避免了错误码机制的一些不足,可以在 一次捕获多个异常。异常对象包含错误信息、错误码、错误行号、文件、上下文,更方便定位问题。

Exception 特点

Exception 是必须手动抛出并且可被捕获的。如果抛出的异常未被捕获,则导致 Fatal error,并使得代码停止执行。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇