set_error_handler仅能捕获E_WARNING、E_NOTICE、E_USER_*等可恢复错误,无法处理E_ERROR、E_PARSE、E_CORE_ERROR等致命错误;必须返回true才生效,且受error_reporting级别和注册顺序限制。

set_error_handler 只能捕获“可恢复”的错误,对致命类错误完全无效。它不是万能兜底,而是一个有明确边界的运行时拦截机制。以下错误类型 无论你怎么配置,都进不了你的 handler 函数:
完全无法捕获的致命错误(E_* 常量)
这些错误发生时,PHP 立即中止脚本执行,不给任何回调机会:
- E_ERROR:如调用未定义函数、访问不存在的类、内存耗尽
-
E_PARSE:语法解析失败,比如
if ($a = 1 {缺少右括号 - E_CORE_ERROR:PHP 启动过程中的核心错误(如扩展加载失败)
- E_COMPILE_ERROR:脚本编译阶段出错(如 use 语句语法错误)
-
E_USER_ERROR:虽然由
trigger_error(..., E_USER_ERROR)主动触发,但它被设计为“不可恢复”,set_error_handler不接管 -
E_RECOVERABLE_ERROR(PHP 5.2+):如类型转换失败导致对象无法实例化——注意:PHP 7+ 已将其升级为
TypeError异常,不再走 error 流程
PHP 8.4 中新增的“伪致命”场景(本质是 Fatal error)
这些不是传统错误级别,而是语言语义强化后直接抛出的 Fatal error,绕过所有 error 处理器:
- 修改
public readonly属性(构造后赋值)→Fatal error: Cannot modify readonly property - 函数参数/返回值类型声明不匹配(如期望
int,传入null)→Fatal error: Uncaught TypeError - 访问未初始化的
readonly属性 →Fatal error: Uninitialized readonly property - 调用已弃用但尚未移除的函数(部分情况在 8.4 中升级为 fatal)
其他明确排除项
以下情况也永远不会触发你的 handler:
立即学习“PHP免费学习笔记(深入)”;
-
error_reporting 当前值未包含该错误级别(例如设为
0或E_ALL & ~E_NOTICE,则E_NOTICE就不会上报) - 错误发生在
set_error_handler()调用之前(如入口文件顶部之前的语法错误) - 框架或 Composer 库已注册自己的 handler,且你的调用被覆盖或顺序靠后
- handler 函数本身返回
false或未返回true,导致 PHP 回退到默认处理



















