PHP 的 SPL 里自带了 13 种 Exception,很多看起来意思也都差不多,那么到底它们应该在什么时候使用?各自的意义又有什么不同?
SPL 的 Exception,只有两个是直接继承自 \Exception 的。一个是 RuntimeException,一个是 LogicException。另外 11 个 Exceptions 都是又继承自它们。所以只要搞清楚它们两兄弟的区别,整个 SPL Exception 也就搞清楚一大半了。
RuntimeException 顾名思义,是运行时的异常。相对应的,LogicException 则是编译时的异常。说到这里,可能有的小伙伴就会问了,PHP 不是解释性脚本语言吗,怎么还分编译时和运行时呢?小伙伴的话说得很对(当然 PHP 也是有代码 => opcode 这个过程的,可以看作编译),但这个概念不能直接套用在 Exception 上。我们看看 PHP 官方文档对这两种 Exception 的阐述:
RuntimeException: Exception thrown if an error which can only be found on runtime occurs.
LogicException: Exception that represents error in the program logic. This kind of exceptions should directly lead to a fix in your code.
也就是说,RuntimeException 这种意外,往往是用户造成,是代码调用者无法通过写更多逻辑代码来避免的。比如封装一个 ORM,在找不到数据的时候返回 NotFoundException(继承自 RuntimeException),ORM 调用者也无法避免此意外的产生,只能根据 NotFoundException 来作出意外处理,比如再抛出 Http404Exception 什么的。
而 LogicException 呢,则是相关代码创作人可以避免的,按照上面引用官方的说法,这类 Exception 都是应该被直接修复掉的。比如说你调用一个作除法的函数,抛出一个除数为 0 的 LogicException,函数使用者就应该对代码除数先作检查,避免用户输入 0 的时候还去调用此函数。
由此可见相对于 RuntimeException 而言,LogicException 更像是跟调用者说:你的调用方式不对,请检查您的代码!
说完 Logic/Runtime Exception 的区别,我们在看看其他 SPL 提供的 Exception 的意义:

