error_get_last在set_error_handler中拿不到当前错误,因为它不记录被自定义处理器捕获的错误;应直接使用回调函数的$errno、$errstr等参数获取错误信息。

error_get_last 为什么在 set_error_handler 里拿不到错误?
因为 error_get_last 返回的是「脚本执行过程中最后一次发生的 PHP 错误」,但它不包括被 set_error_handler 捕获的错误——这些错误根本不会触发 PHP 默认的错误记录机制,也就不会写入 last error 缓冲区。
换句话说:error_get_last 和自定义错误处理器是两条平行线,直接调用它在 handler 内部永远返回 null 或上一个未被捕获的错误(比如 parse error),不是你刚遇到的那个 warning/notice。
想在自定义 handler 中拿到当前错误信息,该怎么做?
答案很简单:别依赖 error_get_last,直接用 set_error_handler 回调函数的参数。PHP 会把错误级别、消息、文件、行号原样传进来。
-
$errno:错误类型(如E_WARNING、E_NOTICE) -
$errstr:错误消息字符串 -
$errfile:出错的文件路径 -
$errline:出错的行号
示例:
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
// 这里的 $errstr 就是你要的“当前错误消息”
error_log("[$errno] $errstr in $errfile:$errline");
// 不要在这里调用 error_get_last() —— 它没用
});
trigger_error('Something went wrong', E_USER_WARNING);
什么情况下 error_get_last 才真正有用?
它只适合用在「错误未被捕获、且已自然结束」之后的上下文中,比如:
- 在
register_shutdown_function里兜底捕获致命错误(E_ERROR、E_PARSE等) - 在
try/catch外围检查是否发生了未捕获的致命错误(注意:catch捕不到E_ERROR) - 执行完一段可能出错的代码后,立刻检查结果(比如
file_get_contents失败但没抛异常时)
典型用法:
register_shutdown_function(function () {
$error = error_get_last();
if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR])) {
error_log("Fatal: {$error['message']} in {$error['file']}:{$error['line']}");
}
});
容易踩的坑:混淆错误类型和错误传播行为
error_get_last 对 E_USER_* 类错误也不可靠——如果你用 trigger_error 触发了一个 E_USER_WARNING,又设置了 handler,那这个错误就被 handler 接走了,error_get_last 不会更新;但如果 handler 中调用了 return false 表示“不接管”,PHP 才会继续走默认流程并更新 last error,这种行为极难预测且版本间有差异。
所以真实项目中:只要用了 set_error_handler,就彻底放弃 error_get_last 来获取当前错误;需要日志或上下文,老老实实从 handler 参数取。
最常被忽略的一点:error_get_last 的返回值是数组,但它的 type 字段是整数,不是常量名——打印调试时别直接 echo $e['type'],否则看到的是数字,得手动映射回 E_* 常量才看得懂。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











