1. PHP错误处理概述:错误级别、错误报告配置、错误处理的重要性
1.1 错误处理——被忽视的基石
说实话,我见过太多PHP项目,代码写得花里胡哨,但错误处理一塌糊涂。
我记得刚入行那会儿,有个线上商城项目,用户下单时偶尔会白屏。查了半天,原来是某个文件引入路径写错了,PHP直接抛了个致命错误。用户看到的不是友好的提示,而是赤裸裸的错误信息——数据库密码都暴露了。
那次之后,我彻底明白了:错误处理不是锦上添花,而是系统的安全底线。
你想想看,一个没有错误处理的系统,就像一辆没有刹车的车。平时可能跑得挺欢,一旦出问题,就是灾难。
1.2 PHP错误级别——你得知道敌人长什么样
PHP的错误不是铁板一块。它分很多种,每种的处理方式都不一样。
我个人习惯把错误级别分成三大类:
| 类别 | 常量 | 值 | 说明 |
|---|---|---|---|
| 致命错误 | E_ERROR | 1 | 脚本直接挂掉,比如调了不存在的函数 |
| 警告 | E_WARNING | 2 | 脚本继续跑,但可能结果不对 |
| 通知 | E_NOTICE | 8 | 小问题,比如用了未定义的变量 |
| 解析错误 | E_PARSE | 4 | 语法写错了,脚本根本跑不起来 |
| 用户错误 | E_USER_ERROR | 256 | 你自己用trigger_error抛出来的 |
关键点:E_ERROR和E_PARSE这类致命错误,你没法用常规的try-catch捕获。它们会直接终止脚本执行。这一点很多新手会踩坑。
除了这些,还有E_STRICT(建议你改的写法)、E_DEPRECATED(即将废弃的功能)等等。完整的列表可以去PHP官网查,但上面这几个是日常开发中最常见的。
1.3 错误报告配置——别让错误裸奔
配置错误报告,说白了就是两件事:开发环境看得到错误,生产环境看不到错误。
我曾经接手过一个项目,生产环境的php.ini里把display_errors设成了On。结果呢?用户一访问,满屏的Notice和Warning。更可怕的是,数据库连接信息也随着错误信息一起暴露了。
正确的做法是这样的:
开发环境(php.ini配置)
; 显示所有错误
error_reporting = E_ALL
; 把错误输出到屏幕
display_errors = On
; 同时记录到日志
log_errors = On
error_log = /var/log/php_errors.log
生产环境(php.ini配置)
; 还是报告所有错误,但别给用户看
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
; 全部记到日志里
log_errors = On
error_log = /var/log/php_errors.log
我的小技巧:在项目入口文件(比如index.php)里用error_reporting()函数动态设置,比改php.ini更灵活。特别是多个项目共用同一台服务器的时候。
<?php
// 开发环境
error_reporting(E_ALL);
ini_set('display_errors', '1');
// 生产环境(注释掉上面,启用下面)
// error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
// ini_set('display_errors', '0');
// ini_set('log_errors', '1');
1.4 错误处理的重要性——不只是修Bug
你可能觉得,错误处理不就是把Bug修好吗?
嗯,这只是最表层的作用。往深了说,它关系到三个方面:
- 安全性——错误信息里可能包含路径、SQL语句、甚至密码。暴露出去就是给黑客递刀子。
- 用户体验——用户看到「Fatal Error」会怎么想?这网站靠谱吗?
- 可维护性——没有日志,线上出了Bug你连从哪查起都不知道。
我记得有一次,一个客户反馈说「后台导出Excel偶尔会失败」。这个问题复现概率很低,大概1%左右。如果没有日志系统,这种Bug基本无解。幸好我们当时把错误都记到了日志里,一查发现是某个特殊字符导致Excel库崩溃了。
避坑指南:我曾经见过一个项目,把display_errors和log_errors都关了。理由是「反正线上没错误」。结果呢?用户反馈功能异常,开发团队花了三天才定位到问题——一个简单的变量名拼写错误。没有日志,你连错误的方向都找不到。
1.5 错误与异常——别搞混了
很多新手会把PHP的错误(Error)和异常(Exception)混为一谈。我简单说一下区别:
- 错误:PHP引擎自己触发的,比如语法错误、调用未定义函数。你没法用try-catch捕获。
- 异常:程序员主动抛出的,比如「用户不存在」、「余额不足」。可以用try-catch处理。
不过PHP也提供了一些机制,让你能把错误转成异常。这个我们后面章节会详细讲,这里先留个印象。
1.6 小结
这一章我们聊了PHP错误的基本概念。说白了,错误处理就是三件事:知道发生了什么错误、把错误记下来、别让用户看到不该看的东西。
下一章,我会带你手写一个自定义错误处理器。到时候你会发现,原来错误处理也可以很优雅。
课后思考:你现在去检查一下你的项目,display_errors是不是还开着?如果是,赶紧关掉。这是最基础也最容易被忽视的安全隐患。