PHP 错误处理完整指南
PHP 提供了多种错误处理机制,确保在应用程序发生错误时,能够正确地 捕获、记录、显示 并采取适当的处理措施。本文将介绍 PHP 错误处理的完整方案,包括 错误级别、错误日志、异常处理、错误处理函数 等内容。
1. PHP 错误类型(错误级别)
PHP 具有多个错误级别,每种级别代表不同的严重程度。以下是常见的错误级别:
| 错误级别 | 说明 |
|---|---|
E_ERROR | 致命错误,脚本终止执行 |
E_WARNING | 警告,不会终止脚本,但可能会导致问题 |
E_NOTICE | 通知,可能的代码逻辑错误 |
E_PARSE | 解析错误,通常由语法错误引起 |
E_DEPRECATED | 不推荐使用,表示某些函数或特性将被废弃 |
E_STRICT | 强制标准,建议改进代码以符合 PHP 规范 |
E_ALL | 所有错误(不包括 E_STRICT) |
可以使用 error_reporting() 设定 PHP 错误级别。例如:
error_reporting(E_ALL & ~E_NOTICE); // 报告所有错误,但忽略 NOTICE 级别
2. 显示错误与记录日志
(1) 显示错误
在开发环境下,通常需要显示错误信息,以便调试问题。可以使用 display_errors 设置:
ini_set('display_errors', 1);
error_reporting(E_ALL);
在 php.ini 中也可以配置:
display_errors = On
error_reporting = E_ALL
📌 生产环境(线上环境)应禁用错误显示,以防止泄露敏感信息:
ini_set('display_errors', 0);
(2) 记录错误日志
在生产环境下,推荐将错误记录到日志文件,而不是直接显示在页面上:
ini_set('log_errors', 1);
ini_set('error_log', '/var/log/php_errors.log');
error_reporting(E_ALL);
在 php.ini 配置:
log_errors = On
error_log = /var/log/php_errors.log
3. 使用 try-catch 处理异常
PHP 提供了 try-catch 机制来捕获异常,确保应用程序不会因致命错误而崩溃。
示例:捕获异常
function divide($a, $b) {
if ($b == 0) {
throw new Exception("除数不能为零");
}
return $a / $b;
}
try {
echo divide(10, 0);
} catch (Exception $e) {
echo "捕获到异常: " . $e->getMessage();
}
多个 catch 处理不同异常
try {
throw new RuntimeException("运行时异常");
} catch (InvalidArgumentException $e) {
echo "参数异常: " . $e->getMessage();
} catch (RuntimeException $e) {
echo "运行时异常: " . $e->getMessage();
} catch (Exception $e) {
echo "通用异常: " . $e->getMessage();
}
4. 自定义错误处理
可以使用 set_error_handler() 定义自己的错误处理函数,将错误转换为异常,或者记录错误日志。
示例:自定义错误处理函数
function customErrorHandler($errno, $errstr, $errfile, $errline) {
$logMessage = "错误级别: [$errno] $errstr - $errfile:$errline\n";
error_log($logMessage, 3, "/var/log/php_custom_errors.log");
if ($errno == E_USER_ERROR) {
echo "致命错误,请联系管理员。";
exit();
}
return true;
}
// 设置自定义错误处理函数
set_error_handler("customErrorHandler");
// 触发错误
echo $undefined_variable; // 触发 NOTICE
trigger_error("自定义警告", E_USER_WARNING);
5. 自定义异常处理
除了 set_error_handler(),还可以使用 set_exception_handler() 处理未捕获的异常。
示例:自定义异常处理
function customExceptionHandler($exception) {
$errorMsg = "未捕获异常: " . $exception->getMessage() . "\n";
error_log($errorMsg, 3, "/var/log/php_custom_exceptions.log");
echo "系统错误,请稍后再试!";
}
// 设置自定义异常处理函数
set_exception_handler("customExceptionHandler");
// 触发异常
throw new Exception("数据库连接失败");
6. 终止脚本时执行(register_shutdown_function)
PHP 提供 register_shutdown_function(),可以在脚本终止时执行特定代码。例如:
function shutdownHandler() {
$error = error_get_last();
if ($error && $error['type'] === E_ERROR) {
error_log("致命错误: {$error['message']} in {$error['file']} on line {$error['line']}", 3, "/var/log/php_shutdown_errors.log");
echo "系统发生错误,请稍后再试。";
}
}
// 注册终止处理函数
register_shutdown_function("shutdownHandler");
用途:
- 记录 致命错误(
E_ERROR)导致的脚本终止 - 发送错误通知(如邮件、Slack 报警)
7. PHP7 及以上的错误处理
PHP 7 引入了 Error 类,使错误可以像异常一样被捕获:
try {
nonExistentFunction(); // 调用不存在的函数
} catch (Error $e) {
echo "捕获到错误: " . $e->getMessage();
}
这样,即使是致命错误,也不会直接终止脚本,而是可以进行适当的处理。
8. 结合日志记录(Monolog)
在复杂应用中,建议使用 Monolog 进行日志管理:
composer require monolog/monolog
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$log = new Logger('app');
$log->pushHandler(new StreamHandler('/var/log/app.log', Logger::WARNING));
$log->warning('这是一条警告日志');
$log->error('这是一条错误日志');
📌 Monolog 支持 Slack、数据库等多种日志存储方式。
9. 错误处理最佳实践
✅ 开发环境
display_errors = Onerror_reporting = E_ALLlog_errors = On
✅ 生产环境
display_errors = Offerror_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATEDlog_errors = On(写入日志)
✅ 推荐
- 使用
try-catch处理异常 - 配置
set_error_handler()处理非致命错误 - 配置
set_exception_handler()处理未捕获异常 register_shutdown_function()捕获E_ERROR- 使用
Monolog进行高级日志管理
总结
| 方案 | 说明 |
|---|---|
try-catch | 捕获异常 (Exception) |
set_error_handler() | 处理自定义错误 |
set_exception_handler() | 处理未捕获异常 |
register_shutdown_function() | 捕获致命错误 (E_ERROR) |
error_log() | 记录错误日志 |
Monolog | 高级日志管理 |
这样可以 提升 PHP 应用的稳定性和安全性,避免因错误导致程序崩溃。更多详细内容请关注其他相关文章!