error_get_last捕获不到Fatal Error,因为PHP遇到Fatal Error时立即中止脚本执行,后续代码(包括error_get_last)根本不会运行;它仅对E_WARNING、E_NOTICE等可恢复的运行时错误有效,而Fatal Error需通过register_shutdown_function+error_get_last在脚本终止前兜底获取。

error_get_last 为什么捕获不到 Fatal Error?
error_get_last 只能返回最近一次发生的错误,但它**不处理未被捕获的致命错误(Fatal Error)**——因为 PHP 在遇到 Fatal Error 时会立即中止脚本执行,error_get_last 根本没机会被调用。比如 call to undefined function 或 Class not found 这类错误,一旦触发,后续代码(包括 error_get_last())直接不执行。
所以别指望在 try/catch 里包住致命错误再调用它——Exception 捕获不了 Fatal Error,它们属于不同错误层级。
什么场景下 error_get_last 真正有用?
它只对「可恢复的运行时错误」有效,比如:E_WARNING、E_NOTICE、E_USER_ERROR 等非终止类错误。典型使用场景:
- 在
set_error_handler回调里主动触发错误后,立刻用error_get_last获取细节 - 调用可能出警告的函数(如
fopen打开失败、json_decode解析失败但没抛异常)后,立刻检查 - 配合
error_reporting(0)关闭显示但保留记录时,靠它捞最后一口错误信息
示例:
立即学习“PHP免费学习笔记(深入)”;
error_reporting(E_ALL & ~E_WARNING);
$result = @file_get_contents('/nonexistent.txt');
if ($result === false) {
$last = error_get_last();
if ($last && $last['type'] === E_WARNING) {
echo "文件读取失败:{$last['message']}";
}
}
替代方案:如何真正捕获 Fatal Error?
PHP 7+ 引入了 Throwable 接口,但 Fatal Error 仍不能被 try/catch 捕获。唯一可靠方式是注册 register_shutdown_function + error_get_last 组合:
-
register_shutdown_function保证脚本结束前执行,哪怕因Fatal Error中止 - 此时调用
error_get_last才可能拿到致命错误信息 - 注意:必须在脚本开头就注册,否则注册前发生的致命错误无法捕获
示例:
立即学习“PHP免费学习笔记(深入)”;
register_shutdown_function(function () {
if ($error = error_get_last()) {
if (in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
// 记录或上报 $error['message'], $error['file'], $error['line']
}
}
});
容易忽略的兼容性与陷阱
error_get_last 返回数组结构不稳定,不同 PHP 版本字段略有差异:
- PHP 7.4+ 增加了
file和line字段,但低版本可能为空 -
type是整数,别直接跟字符串比较(比如写$err['type'] === 'E_ERROR'),要用E_ERROR常量 - 多次调用
error_get_last不会清空结果,但新错误发生后会覆盖旧值——它只存“最后一次”,不是队列 - CLI 模式下某些致命错误(如内存耗尽)可能连 shutdown 函数都不触发,这时
error_get_last也失效
最常被漏掉的一点:它不返回错误上下文(比如堆栈),要完整诊断还得配合 debug_backtrace 或日志系统。



















