PHP错误级别包括E_ERROR(1,致命错误)、E_WARNING(2,运行时警告)、E_PARSE(4,解析错误)等,通过位运算组合;error_reporting()直接设置错误掩码,优先级高于ini_set();生产环境应记录而非关闭错误。

PHP错误级别有哪些:E_ERROR、E_WARNING这些数字代表什么
PHP的错误级别不是随便起的名字,每个E_*常量对应一个整数,PHP用位运算来组合它们。比如E_ERROR是1,E_WARNING是2,E_PARSE是4——你看到error_reporting(7),其实就是E_ERROR | E_WARNING | E_PARSE(1|2|4=7)。
常见级别按严重性从高到低:
-
E_ERROR:致命错误,脚本立刻终止,比如调用不存在的函数 -
E_WARNING:运行时警告,脚本继续执行,比如include一个不存在的文件 -
E_NOTICE:非致命提示,比如访问未定义的数组键或变量 -
E_DEPRECATED:已弃用特性警告,比如用mysql_connect()(PHP 7.0+ 已移除) -
E_STRICT:建议性编码规范提醒,不影响执行,但可能影响跨版本兼容性 -
E_ALL:包含几乎所有级别(PHP 8.0+ 不含E_DEPRECATED和E_USER_DEPRECATED)
ini_set('error_reporting', ...) 和 error_reporting() 的区别在哪
两者都能改错误报告级别,但作用时机和范围不同:ini_set('error_reporting', ...)是运行时修改配置项,而error_reporting()是直接设置当前脚本的错误掩码,更底层、更可靠。
容易踩的坑:
立即学习“PHP免费学习笔记(深入)”;
- 在
php.ini里设了error_reporting = E_ALL & ~E_NOTICE,但脚本里用error_reporting(E_ALL),后者会生效——函数调用优先级高于配置项 -
ini_set('error_reporting', 'E_ALL')会失败,因为这个值必须是整数,传字符串会被转成0(即关闭所有错误报告) -
error_reporting(0)能彻底关掉错误输出,但不会影响set_error_handler()捕获——它只是不显示/记录,错误仍发生
开发环境开E_ALL,生产环境为什么不能简单设为0
关掉所有错误看似“干净”,实则埋雷。PHP脚本出错不报,可能只表现为白屏、空响应或数据异常,排查成本远高于日志里多几条NOTICE。
合理做法是分层控制:
- 开发环境:
error_reporting(E_ALL)+display_errors = On+log_errors = On - 生产环境:
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED)+display_errors = Off+log_errors = On+error_log = /var/log/php/error.log - 特别注意:
display_errors = Off只是不输出到浏览器,不影响error_log()或自定义错误处理器
为什么设置了 error_reporting 还看不到 Notice
最常见原因是display_errors被关了,或者error_log路径不可写,导致错误“消失”。另外,某些SAPI(如CLI)默认display_errors为Off,即使error_reporting开着也看不到屏幕输出。
快速验证步骤:
- 加一行
var_dump(ini_get('display_errors'), ini_get('error_reporting'), ini_get('log_errors'));确认实际值 - 手动触发Notice:
echo $undefined_var;,看是否进日志或屏幕 - 检查
error_log路径权限:touch /var/log/php/test && rm /var/log/php/test(CLI下测试) - Apache模块下,虚拟主机配置可能覆盖
php.ini,用phpinfo()查“Loaded Configuration File”和“Scan this dir for additional .ini files”
真正难的不是记全所有E_*常量,而是理解error_reporting只是“告诉PHP哪些错误值得理”,而display_errors、log_errors、error_log才是决定“理了之后往哪扔”。三者不配齐,设置再对也看不见错误。










