php基础(08):PHP7异常和错误处理机制

本文详细介绍了PHP7中的异常处理机制,包括Error类与Exception的区别。PHP7将大部分错误转换为可捕获的Error异常,允许通过try/catch块处理。同时,文章列举了不同类型的Error子类,如ArithmeticError、DivisionByZeroError等,并讨论了如何使用set_exception_handler()和set_error_handler()处理异常。此外,还提到了 Throwable接口的重要性,它是Exception和Error的共同基类,可用于捕获所有异常类型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.php异常是什么?和错误有什么区别?

  • PHP 中将代码自身异常(一般是环境或者语法非法所致)称作错误 Error,将运行中出现的逻辑错误称为异常 Exception
  • 错误是没法通过代码处理的,而异常则可以通过 try/catch 来处理
  • PHP 7 改变了大多数错误的报告方式。不同于传统(PHP 5)的错误报告机制,现在大多数错误被作为 Error 异常抛出。

    这种 Error 异常可以像 Exception 异常一样被第一个匹配的 try / catch 块所捕获。如果没有匹配的 catch 块,则调用异常处理函数(事先通过 set_exception_handler() 注册)进行处理。 如果尚未注册异常处理函数,则按照传统方式处理:被报告为一个致命错误(Fatal Error)。

  • Error 类并非继承自 Exception 类,所以不能用 catch (Exception $e) { ... } 来捕获 Error。你可以用 catch (Error $e) { ... },或者通过注册异常处理函数( set_exception_handler())来捕获 Error

try {
    echo 10/0;
} catch (\Exception $e) {
    echo $e->getMessage();  // Division by zero
}

 echo 10/0; // ErrorException: Division by zero in file
$file=fopen("welcome.txt","r"); // ErrorException: fopen(welcome.txt): failed to open stream: No such file or directory in file

注意:php5上面代码是捕获不到的,php7可以。

错误等级

      Fatal Error:致命错误(脚本终止运行)
          E_ERROR         // 致命的运行错误,错误无法恢复,暂停执行脚本
          E_CORE_ERROR    // PHP启动时初始化过程中的致命错误
          E_COMPILE_ERROR // 编译时致命性错,就像由Zend脚本引擎生成了一个E_ERROR
          E_USER_ERROR    // 自定义错误消息。像用PHP函数trigger_error(错误类型设置为:E_USER_ERROR)
  
      Parse Error:编译时解析错误,语法错误(脚本终止运行)
          E_PARSE  //编译时的语法解析错误
  
     Warning Error:警告错误(仅给出提示信息,脚本不终止运行)
         E_WARNING         // 运行时警告 (非致命错误)。
         E_CORE_WARNING    // PHP初始化启动过程中发生的警告 (非致命错误) 。
         E_COMPILE_WARNING // 编译警告
         E_USER_WARNING    // 用户产生的警告信息
 
     Notice Error:通知错误(仅给出通知信息,脚本不终止运行)
         E_NOTICE      // 运行时通知。表示脚本遇到可能会表现为错误的情况.
         E_USER_NOTICE // 用户产生的通知信息。

2.php拦截异常的函数

(1)set_exception_handler() 设置默认的异常处理程序,用于没有用 try/catch 块来捕获的异常。 在 exception_handler 调用后异常会中止。:

set_exception_handler(callable $exception_handler): callable

(2)set_error_handler() 设置用户自定义的错误处理函数:

set_error_handler(callable $error_handler, int $error_types = E_ALL | E_STRICT): mixed

PHP 7.2.0 后此参数被弃用了。 极其不建议依赖它。

(3)register_shutdown_function() — 注册一个会在php中止时执行的函数

register_shutdown_function(callable $callbackmixed $parameter = ?, mixed $... = ?): void

3.Throwable

PHP7 新增了一个全新的接口 Throwable,Exception 和 Error 都实现了 Throwable 接口

Throwable 接口:

interface Throwable
{
    public function getMessage(): string;
    public function getCode(): int;
    public function getFile(): string;
    public function getLine(): int;
    public function getTrace(): array;
    public function getTraceAsString(): string;
    public function getPrevious(): Throwable;
    public function __toString(): string;
}

class Exception implements Throwable {
...
}

class Error implements Throwable {
...
}

Throwable 可以捕获 try/catch 块中 Exception 和 Error 对象(或是任何未来可能)的异常类型。

如果要捕获特定类型的异常最好使用对应的 ***Exception 处理,Throwable 更偏向于处理未知错误和系统级错误。

在 PHP7 中,要捕获所有的错误应该使用 Throwable 而不是 Exception。

try {
// 逻辑代码
} catch (Throwable $t) {
// 补救处理
}

Error 内部错误

PHP7 中 fatal 或 recoverable 级别的错误都能抛出一个 Error 实例。可以使用 try/catch 块来捕获。$user = [];

try {
     $user->getName();
} catch (Error $e) {
    // Call to a member function getName() on arrayecho
    $e->getMessage();
}

Error 类细分出以下子类:

        ArithmeticError:位移操作负数位或调用 intdiv() 时分子是 PHP_INT_MIN 且分母是 -1 (这个使用除法运算符的表达式:PHP_INT_MIN / -1,结果是浮点型)

        DivisionByZeroError:intdiv() 的分母是 0 或者取模操作 (%) 中分母是 0

        AssertionError:assert() 的条件不满足

        CompileError:编译错误

        ParseError:include/require 文件或 eval() 代码存在语法错误

        TypeError:函数参数或返回值不符合声明的类型

        ArgumentCountError:递给用户定义的函数或方法的参数太少时被抛出

Exception 异常    

        RuntimeException

        RuntimeExcption是执行异常,指程序身本以外无法由开发者控制的状况。 例如呼叫数据库,但是数据库没有回应,或者呼叫远程 API ,可是 API 却没有传回正确的数值。 另外也包含档案系统或环境的问题,例如程序要抓取的的某个外部档案不存在,或者应该安装的外部函式库没有正常运作,这些因为都不是开发者可以控制的,我们就统称为 RuntimeException。        Web 开发最常见的状况就是数据库连接失败,或者SQL查询错误。 例如 PDO 所丢出来的 PDOException 就是既承自 RuntimeException。 所以我们要判断是否是数据库错误可以这样写:

try {
// some database operation
$db->fetch();
} catch (RuntimeException $e) {
// Database error
} catch (Exception $e) {
// Other error
}

LogicException

        LogicException 则是反过来,属于程序本身的问题,应该要是开发者事前就解决的问题。 例如某个应该要被 Override 的 method 没有被 override,但 class 本身又因故无法设为 abstract 时,我们就在 method 中丢出 LogicException,要求开发者一定要处理这个问题。 另外,class未被引入,呼叫不存在的对象,或是你把数值除以零等等都属于此例外。class Command

{
    public function execute()
    {
        if ($this->handler instanceof Closure) {
            return $this->handler();
        }
        throw new LogicExcpetion('Handler should be callable.');
        
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值