PHP 错误处理:error_reporting() 与 try-catch
PHP 程序运行时可能遇到语法错误、运行时警告或逻辑异常。要让程序稳定可靠,必须主动控制这些错误的显示和处理方式。PHP 提供了两类机制:error_reporting() 控制传统错误(如警告、通知)的报告级别,而 try-catch 结构用于捕获和处理异常(Exception)。两者分工明确,需配合使用。
第一阶段:用 error_reporting() 控制错误显示
PHP 的“错误”(Error)是一类由引擎触发的底层问题,比如访问未定义变量、调用不存在的函数等。这类错误无法用 try-catch 捕获(除非转换为异常),但可通过 error_reporting() 设置哪些级别的错误需要被报告。
- 打开你的 PHP 配置文件
php.ini,找到error_reporting这一行。 - 修改该行的值为所需级别。常用组合如下:
; 开发环境:显示所有错误(包括严格标准)
error_reporting = E_ALL
; 生产环境:仅记录严重错误,不显示给用户
error_reporting = E_ERROR | E_WARNING | E_PARSE
- 如果无法修改
php.ini,可在 PHP 脚本开头用函数动态设置:
<?php
// 开发时开启全部错误报告
error_reporting(E_ALL);
// 生产环境关闭所有错误显示(但仍可记录日志)
error_reporting(0);
- 同步关闭错误输出(防止敏感信息泄露):
// 不在浏览器中显示错误
ini_set('display_errors', '0');
// 但将错误写入日志(需确保日志路径可写)
ini_set('log_errors', '1');
ini_set('error_log', '/var/log/php_errors.log');
PHP 的错误级别是位掩码常量,可通过按位或 | 组合。常见级别含义如下:
| 常量 | 含义 | 是否建议生产环境显示 |
|---|---|---|
E_ERROR |
致命运行时错误(如内存耗尽) | ❌ |
E_WARNING |
运行时警告(如 include 文件不存在) |
❌ |
E_NOTICE |
通知(如使用未初始化变量) | ❌ |
E_STRICT |
编码建议(未来兼容性问题) | ❌ |
E_ALL |
所有错误、警告、通知 | ✅ 仅开发环境 |
第二阶段:用 try-catch 处理异常
“异常”(Exception)是程序主动抛出的对象,代表可预期的逻辑错误(如数据库连接失败、文件权限不足)。这类问题必须用 try-catch 结构捕获,否则会导致脚本终止。
- 包裹可能出错的代码到
try块中:
<?php
try {
$pdo = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
// 捕获数据库异常
error_log("DB Error: " . $e->getMessage());
echo "服务暂时不可用,请稍后再试。";
}
- 抛出自定义异常以处理业务逻辑错误:
function withdraw($balance, $amount) {
if ($amount > $balance) {
throw new Exception("余额不足");
}
return $balance - $amount;
}
try {
$newBalance = withdraw(100, 150);
} catch (Exception $e) {
echo "操作失败:" . $e->getMessage();
}
```
3. **多层捕获**不同类型的异常:
```php
try {
// 可能抛出多种异常的代码
} catch (SpecificException $e) {
// 处理特定异常
} catch (Exception $e) {
// 捕获所有其他异常(兜底)
}
```
4. **确保资源清理**(无论是否出错):
```php
$fp = fopen('data.txt', 'r');
try {
// 读取并处理文件
} finally {
// PHP 5.5+ 支持 finally
fclose($fp);
}
```
> 注意:传统错误(如 `E_WARNING`)默认不会变成异常。若想统一用 `try-catch` 处理,需先将错误转为异常。
---
## 第三阶段:将错误转换为异常(高级用法)
通过设置自定义错误处理器,可把 PHP 错误自动转为 `ErrorException`,从而用 `try-catch` 统一管理。
1. **注册错误处理器**:
```php
<?php
function exception_error_handler($severity, $message, $file, $line) {
if (!(error_reporting() & $severity)) {
// 当前错误级别被忽略,直接返回
return;
}
throw new ErrorException($message, 0, $severity, $file, $line);
}
set_error_handler("exception_error_handler");
- 现在传统错误也能被捕获:
try {
echo $undefinedVariable; // 触发 E_NOTICE
} catch (ErrorException $e) {
echo "捕获到错误:" . $e->getMessage();
}
- 恢复默认行为(如需):
restore_error_handler(); // 移除自定义处理器
此方法适合希望用统一异常机制处理所有问题的项目,但会改变原有错误处理流程,需谨慎评估兼容性。
最佳实践组合方案
根据环境选择配置组合:
- 开发环境:
error_reporting(E_ALL)ini_set('display_errors', '1')- 启用错误转异常(便于调试)
- 生产环境:
error_reporting(E_ERROR | E_WARNING | E_PARSE)ini_set('display_errors', '0')ini_set('log_errors', '1')- 使用
try-catch处理关键业务异常 - 不启用错误转异常(避免意外中断)
始终记录错误日志,即使不显示给用户。日志是排查问题的唯一依据。

暂无评论,快来抢沙发吧!