PHP 怎么PHP 错误处理注册

wen PHP项目 1

本文目录导读:

PHP 怎么PHP 错误处理注册

  1. 使用 set_error_handler()
  2. 使用 set_exception_handler()
  3. 同时注册错误和异常处理
  4. 使用 error_reporting() 控制错误级别
  5. 使用 register_shutdown_function()
  6. 最佳实践:生产环境的错误处理

在 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() 手动触发错误 自定义错误

建议在生产环境中:

  1. 关闭 display_errors
  2. 开启 log_errors 并指定日志文件
  3. 使用 set_error_handler()set_exception_handler() 统一处理
  4. 使用 register_shutdown_function() 捕获致命错误
  5. 返回友好的错误页面给用户

抱歉,评论功能暂时关闭!