第 4 章 · 面向对象 · 第 4.4 课
错误与异常处理
程序总会遇到意外:用户输入了非法数据、文件不存在、数据库连不上。异常(Exception)是报告“这件事做不下去了”的标准方式:
throw new Exception("说明")抛出异常,当前函数立刻停止执行。- 异常会一层层往上传,直到被
try { } catch (异常类型 $e) { }接住。 finally里的代码不管有没有异常都会执行,适合做收尾工作。- 没人接住的异常会让整个程序中止,并报
Uncaught ...错误。
自定义异常
继承 Exception 就能定义自己的异常类型,还可以附带额外的数据。catch 按类型匹配,所以调用方可以针对不同的问题做不同的处理。PHP 内置了一批常用类型:InvalidArgumentException(参数不对)、RangeException(超出范围)、RuntimeException(运行时问题)等。
Error:PHP 自己抛出的错误
PHP 8 里,很多严重错误(调用不存在的函数、类型不对、除以 0)也会以 Error 的形式抛出,同样可以被 catch。Exception 和 Error 都实现了 Throwable 接口,catch (Throwable $e) 能接住所有东西,但一般只在最外层这样兜底。
选择题
finally 块什么时候执行?
练习 1
校验年龄
已通过写函数 parseAge(string $input): int,把用户输入的字符串转成年龄:
- 不是数字(用
is_numeric判断):抛出InvalidArgumentException,消息是不是数字 - 小于 0 或大于 150:抛出
RangeException,消息是年龄超出范围(负数也是数字,只是超出范围) - 否则返回整数年龄
练习 2
安全地批量处理
已通过$inputs 里有好几个待处理的年龄,其中有非法数据。用上一题的 parseAge(已经写好了)逐个处理:合法的输出年龄,非法的输出错误消息,一个出错不能影响后面的。期望输出:
18
不是数字
年龄超出范围
42