PHP 线上报错处理,别把错误直接甩给用户
这是一篇 PHP 错误处理排坑记录。线上最怕的不是报错,而是用户看到了堆栈,开发者却拿不到线索。
异常发生 → 捕获 Throwable → 写入日志 → 返回稳定提示 → 根据 trace 定位问题
很多项目开发环境跑得很舒服,一上生产就开始慌。页面一片空白、接口返回半截 html、日志里只有一句警告,排查成本一下就上来了。
一、用 Throwable 收住错误边界

PHP 7 以后,Throwable 是能被抛出的对象基础接口,Error 和 Exception 都在这条线上。线上入口做兜底时,只抓 Exception 可能漏掉一部分致命错误。
• 控制器入口、队列任务、定时脚本,都适合有一层统一兜底。
• 业务内部可以继续抛 RuntimeException、InvalidArgumentException 这类更具体的异常。
• 兜底层不要吞掉错误,要记录 getMessage()、getFile()、getLine() 和 trace。
用户需要稳定提示,开发者需要完整线索。
这两件事分开做,页面才不会乱,排查也不会断。
二、生产环境关 display_errors,开 log_errors

线上直接打开 display_errors,等于把路径、SQL 片段、调用栈展示给用户。开发阶段可以开,生产环境建议关掉,把错误写进日志。
display_errors = Off log_errors = On error_reporting = E_ALL
• error_reporting 控制哪些级别的错误会被报告。
• display_errors 控制错误是否输出到页面。
• log_errors 控制错误是否写入日志。
错误不该消失,只是不该出现在用户屏幕上。
如果线上页面空白,先看 PHP-FPM、Web 服务器和应用自己的日志。只盯浏览器页面,很容易错过真正原因。
三、日志别只记一句 message

很多日志看起来有记录,实际没法定位。只有一句 Undefined index,没有请求地址、用户、参数摘要、trace,事故复盘会很痛苦。
• 接口请求建议带 request_id,方便串起网关、应用和数据库日志。
• 记录 user_id、路由、请求方法、关键参数摘要,但别写明文密码和 token。
• 队列任务要记录任务 ID 和重试次数,不然很难判断是不是重复消费。
日志不是为了证明出错了,而是为了还原当时发生了什么。
敏感信息要脱敏。能定位问题就够了,不需要把用户隐私一股脑写进文件。
四、接口异常要返回稳定结构

API 报错时最怕响应格式跟着失控。前端期待 JSON,后端吐出一段 HTML 堆栈,用户看到的是加载失败,前端拿到的是解析异常。
{
"code": 500,
"message": "服务暂时不可用",
"request_id": "..."
}
• 对外响应保留稳定字段,比如 code、message、request_id。
• 详细错误写日志,不直接塞进响应体。
• 不同异常可以映射不同状态码,但结构尽量统一。
接口可以失败,但响应格式不能跟着失控。
错误处理的核心不是把所有异常都盖住,而是让用户、前端、后端各自拿到该拿的信息。页面稳定,日志完整,这套系统才算能排查。
我的建议很简单:线上错误处理要分层,展示归展示,日志归日志,告警归告警。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











