php 7+ 起部分 error(如 typeerror、argumentcounterror)可被 try catch 捕获,因它们继承自 throwable;但 fatal error、parse error 等仍不可捕获,需用 register_shutdown_function 补救。

PHP 7+ 之后,Error 也能被 try catch 捕获了
不是所有 Error 都能捕获,但 PHP 7 起把原本“一崩就死”的部分错误(比如 TypeError、ParseError、ArgumentCountError)改成了可抛出的 Error 类实例,它们和 Exception 一样继承自 Throwable,所以能进 catch 块。
- 能捕获:类型不匹配调用、传参个数错、静态方法当实例方法调用等运行时
Error - 不能捕获:真正的
Fatal Error(如内存耗尽、扩展未加载、语法错误导致解析失败)——这些仍会中断脚本,需靠register_shutdown_function()+error_get_last()补救 - 兼容性注意:PHP 5.x 完全无法捕获任何
Error;升级到 PHP 7.0+ 是前提
catch Exception 和 catch Error 的写法差异
直接写 catch (Exception $e) 会漏掉 Error;只写 catch (Error $e) 又会漏掉业务异常。最稳妥的做法是统一用 Throwable:
try {
// 可能出错的代码
} catch (Throwable $e) {
// 这里能同时接住 Exception 和 Error
error_log($e->getMessage());
}
- 不推荐分两个
catch块(除非你要对 Error 和 Exception 做完全不同的日志/响应逻辑) -
instanceof Throwable是安全判断方式,避免对未知对象调用getMessage()报错 - 别在
catch里再抛出新异常却不记录原堆栈——用$e->getTraceAsString()留痕
哪些错误永远进不了 try catch?
真正致命、底层失控的错误,PHP 不给你拦截机会,包括:
Fatal error: Allowed memory size of XXX bytes exhausted-
Fatal error: Class 'XXX' not found(autoload 失败且无对应类定义) -
Parse error: syntax error, unexpected '}'(文件解析阶段就挂了) - 扩展崩溃、SIGSEGV 信号等 C 层面问题
这类问题只能靠 register_shutdown_function() 检查 error_get_last() 是否非空来兜底,但此时脚本已终止,无法“恢复执行”,只能记日志、发告警、清理临时资源。
立即学习“PHP免费学习笔记(深入)”;
业务逻辑里该 throw Exception 还是 trigger_error?
明确一点:自己写的业务校验失败(比如用户余额不足、订单状态非法),必须用 throw new Exception(...);而 trigger_error() 产生的只是传统 PHP 错误(E_USER_WARNING/E_USER_ERROR),它不是 Throwable 子类,try catch 捕不到,只能靠 set_error_handler() 处理。
- 想让上层统一用
try catch控制流?只用Exception(或其子类,如InvalidArgumentException) -
trigger_error()适合调试提示、兼容旧代码、或你确实不想中断流程只想打个标记 - 混用两者会让错误处理路径分裂——有人监听
set_error_handler,有人写catch,维护成本陡增
最容易被忽略的是:很多老项目还在用 trigger_error 模拟异常,结果在新 PHP 版本里既没被 catch 到,又没配好错误处理器,直接变成静默失败或 500。









