本文目录导读:

- 使用 set_error_handler()
- 使用 set_exception_handler()
- 同时注册错误和异常处理
- 使用 error_reporting() 控制错误级别
- 使用 register_shutdown_function()
- 最佳实践:生产环境的错误处理
在 PHP 中,错误处理注册主要涉及以下几个核心函数和机制,我将为你详细介绍最常用的几种方式。
使用 set_error_handler()
这是最常用的自定义错误处理方法,可以捕获大多数运行时错误。
<?php
// 定义错误处理函数
function customErrorHandler($errno, $errstr, $errfile, $errline) {
echo "错误级别: $errno<br>";
echo "错误信息: $errstr<br>";
echo "错误文件: $errfile<br>";
echo "错误行号: $errline<br>";
// 根据错误级别决定是否终止脚本
if ($errno === E_USER_ERROR || $errno === E_ERROR) {
die("严重错误,脚本终止");
}
// 返回 true 表示错误已被处理
return true;
}
// 注册错误处理函数
set_error_handler("customErrorHandler");
// 触发一个错误测试
echo $undefinedVar; // 未定义变量(Notice 级别)
trigger_error("自定义错误", E_USER_WARNING); // 自定义警告
?>
错误处理函数的参数:
$errno: 错误级别(如 E_WARNING, E_NOTICE 等)$errstr: 错误信息$errfile: 发生错误的文件$errline: 错误发生的行号$errcontext(可选): 错误发生时的符号表
使用 set_exception_handler()
用于处理未捕获的异常。
<?php
// 定义默认的异常处理函数
function customExceptionHandler($exception) {
echo "未捕获的异常: " . $exception->getMessage() . "<br>";
echo "在文件: " . $exception->getFile() . " 的第 " . $exception->getLine() . " 行<br>";
// 记录错误日志
error_log("异常: " . $exception->getMessage());
// 显示友好的错误页面(生产环境)
// header('Location: error.html');
}
// 设置异常处理函数
set_exception_handler("customExceptionHandler");
// 测试
throw new Exception("这是一个测试异常");
?>
同时注册错误和异常处理
更完整的错误处理方案:
<?php
// 错误处理
function handleError($errno, $errstr, $errfile, $errline) {
$message = sprintf(
"[%s] 错误: %s 在 %s 第 %d 行",
error_level_string($errno),
$errstr,
$errfile,
$errline
);
// 记录错误日志
error_log($message);
// 开发环境显示错误
if (ini_get('display_errors')) {
echo "<div style='color: red;'>$message</div>";
}
// 不要执行 PHP 内部错误处理
return true;
}
// 异常处理
function handleException($exception) {
$message = sprintf(
"异常: %s 在 %s 第 %d 行",
$exception->getMessage(),
$exception->getFile(),
$exception->getLine()
);
// 记录异常日志
error_log($message);
// 生产环境显示友好错误
if (!ini_get('display_errors')) {
echo "系统发生错误,请稍后再试";
} else {
echo "<pre>$message</pre>";
}
}
// 辅助函数:错误级别转字符串
function error_level_string($level) {
$levels = [
E_ERROR => 'E_ERROR',
E_WARNING => 'E_WARNING',
E_PARSE => 'E_PARSE',
E_NOTICE => 'E_NOTICE',
E_CORE_ERROR => 'E_CORE_ERROR',
E_CORE_WARNING => 'E_CORE_WARNING',
E_COMPILE_ERROR => 'E_COMPILE_ERROR',
E_COMPILE_WARNING => 'E_COMPILE_WARNING',
E_USER_ERROR => 'E_USER_ERROR',
E_USER_WARNING => 'E_USER_WARNING',
E_USER_NOTICE => 'E_USER_NOTICE',
E_STRICT => 'E_STRICT',
E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
E_DEPRECATED => 'E_DEPRECATED',
E_USER_DEPRECATED => 'E_USER_DEPRECATED',
];
return isset($levels[$level]) ? $levels[$level] : 'UNKNOWN';
}
// 注册错误和异常处理
set_error_handler("handleError");
set_exception_handler("handleException");
// 捕获致命错误
register_shutdown_function(function() {
$error = error_get_last();
if ($error !== NULL && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
handleError($error['type'], $error['message'], $error['file'], $error['line']);
}
});
// 测试
// echo $undefinedVar; // 触发 Notice
// trigger_error("测试错误", E_USER_WARNING); // 触发 Warning
// throw new Exception("测试异常"); // 触发异常
?>
使用 error_reporting() 控制错误级别
<?php
// 设置错误报告级别
error_reporting(E_ALL); // 报告所有错误
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED); // 报告所有错误,除了 NOTICE 和 DEPRECATED
error_reporting(0); // 关闭所有错误报告
// 配合 set_error_handler 使用
error_reporting(E_ALL);
set_error_handler(function($errno, $errstr, $errfile, $errline) {
// 只处理指定的错误级别
if (!(error_reporting() & $errno)) {
return false;
}
echo "错误: $errstr";
return true;
});
?>
使用 register_shutdown_function()
捕获致命错误(如内存耗尽、执行超时等):
<?php
function shutdownHandler() {
$error = error_get_last();
if ($error !== NULL) {
// 处理致命错误
echo "致命错误: {$error['message']}<br>";
echo "文件: {$error['file']} 行: {$error['line']}<br>";
// 记录日志
error_log("Fatal error: {$error['message']} in {$error['file']} on line {$error['line']}");
}
}
register_shutdown_function('shutdownHandler');
?>
最佳实践:生产环境的错误处理
<?php
class ErrorHandler {
public static function register() {
// 设置错误报告级别(生产环境)
error_reporting(E_ALL);
// 自定义错误处理
set_error_handler([__CLASS__, 'handleError']);
// 自定义异常处理
set_exception_handler([__CLASS__, 'handleException']);
// 捕获致命错误
register_shutdown_function([__CLASS__, 'handleShutdown']);
// 禁用错误显示
ini_set('display_errors', 0);
// 启用错误日志
ini_set('log_errors', 1);
ini_set('error_log', '/path/to/error.log');
}
public static function handleError($errno, $errstr, $errfile, $errline) {
$message = "Error [$errno] $errstr in $errfile on line $errline";
// 记录错误日志
error_log($message);
// 根据错误级别决定是否显示错误页面
if ($errno == E_ERROR || $errno == E_USER_ERROR) {
self::displayFriendlyError();
exit;
}
return true;
}
public static function handleException($exception) {
$message = "Exception: " . $exception->getMessage() .
" in " . $exception->getFile() .
" on line " . $exception->getLine();
error_log($message);
self::displayFriendlyError();
}
public static function handleShutdown() {
$error = error_get_last();
if ($error !== null &&
in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
error_log("Fatal Error: {$error['message']} in {$error['file']} on line {$error['line']}");
self::displayFriendlyError();
}
}
private static function displayFriendlyError() {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
// 显示友好的错误页面
include 'error_page.php'; // 创建一个简单的错误页面
}
}
// 注册错误处理
ErrorHandler::register();
?>
| 函数/方法 | 用途 | 捕获范围 |
|---|---|---|
set_error_handler() |
自定义错误处理 | 大多数运行时错误(E_WARNING, E_NOTICE 等) |
set_exception_handler() |
自定义异常处理 | 未捕获的异常 |
register_shutdown_function() |
脚本关闭时执行 | 致命错误(E_ERROR 等) |
error_reporting() |
设置错误报告级别 | 控制哪些错误被报告 |
trigger_error() |
手动触发错误 | 自定义错误 |
建议在生产环境中:
- 关闭
display_errors - 开启
log_errors并指定日志文件 - 使用
set_error_handler()和set_exception_handler()统一处理 - 使用
register_shutdown_function()捕获致命错误 - 返回友好的错误页面给用户
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播