PHP 怎么PHP 自定义错误页

wen PHP项目 1

本文目录导读:

PHP 怎么PHP 自定义错误页

  1. 使用 set_error_handler() 自定义错误处理函数(推荐)
  2. 使用 try-catch 处理异常(推荐面向对象方式)
  3. 使用 Apache 的 .htaccess 配置
  4. 使用 Nginx 配置
  5. 完整的错误处理封装示例
  6. 错误页面示例(404.php)
  7. 最佳实践建议

在 PHP 中自定义错误页面,主要有以下几种方式,按推荐程度和场景排序:

使用 set_error_handler() 自定义错误处理函数(推荐)

<?php
// 设置自定义错误处理函数
set_error_handler(function($errno, $errstr, $errfile, $errline) {
    // 记录错误日志
    error_log("错误: [$errno] $errstr in $errfile on line $errline");
    // 显示自定义错误页面
    if (ini_get('display_errors')) {
        // 开发环境:显示详细信息
        echo "<div style='border:1px solid red; padding:20px; margin:20px;'>";
        echo "<h2>系统错误</h2>";
        echo "<p>错误编号: $errno</p>";
        echo "<p>错误信息: $errstr</p>";
        echo "<p>文件: $errfile 第 $errline 行</p>";
        echo "</div>";
    } else {
        // 生产环境:显示友好错误页面
        include 'error_pages/generic_error.php';
    }
    return true;
});
// 恢复之前定义的错误处理
// restore_error_handler();
?>

使用 try-catch 处理异常(推荐面向对象方式)

<?php
// 设置全局异常处理
set_exception_handler(function($exception) {
    // 记录异常
    error_log("未捕获异常: " . $exception->getMessage());
    // 显示自定义错误页面
    http_response_code(500);
    require 'error_pages/500.html';
});
// 在代码中使用 try-catch
try {
    // 可能出错的代码
    $result = 10 / 0;
} catch (DivisionByZeroError $e) {
    // 显示自定义错误
    http_response_code(400);
    include 'error_pages/400_bad_request.php';
    exit;
} catch (Exception $e) {
    // 通用错误处理
    http_response_code(500);
    include 'error_pages/500.php';
    exit;
}
?>

使用 Apache 的 .htaccess 配置

# 在网站根目录的 .htaccess 文件中添加
ErrorDocument 400 /error_pages/400.php
ErrorDocument 401 /error_pages/401.php
ErrorDocument 403 /error_pages/403.php
ErrorDocument 404 /error_pages/404.php
ErrorDocument 500 /error_pages/500.php

使用 Nginx 配置

# 在 nginx 配置中添加
error_page 404 /error_pages/404.html;
error_page 500 502 503 504 /error_pages/50x.html;
location = /error_pages/404.html {
    root /var/www/html;
    internal;
}
location = /error_pages/50x.html {
    root /var/www/html;
    internal;
}

完整的错误处理封装示例

<?php
class ErrorHandler {
    public function __construct() {
        // 设置错误和异常处理
        set_error_handler([$this, 'handleError']);
        set_exception_handler([$this, 'handleException']);
        // 关闭 PHP 显示错误
        ini_set('display_errors', 0);
        ini_set('log_errors', 1);
    }
    public function handleError($errno, $errstr, $errfile, $errline) {
        // 根据错误类型设置对应的 HTTP 状态码
        $statusCode = 500;
        switch ($errno) {
            case E_USER_WARNING:
            case E_WARNING:
                $statusCode = 400;
                break;
            case E_USER_NOTICE:
            case E_NOTICE:
                $statusCode = 200;
                break;
            default:
                $statusCode = 500;
        }
        // 记录错误
        $this->logError($errno, $errstr, $errfile, $errline);
        // 显示错误页面
        $this->displayErrorPage($statusCode, [
            'message' => $errstr,
            'file' => $errfile,
            'line' => $errline
        ]);
        return true;
    }
    public function handleException($exception) {
        $statusCode = $exception->getCode() ?: 500;
        $this->logError(
            get_class($exception), 
            $exception->getMessage(), 
            $exception->getFile(), 
            $exception->getLine()
        );
        $this->displayErrorPage($statusCode, [
            'message' => $exception->getMessage(),
            'file' => $exception->getFile(),
            'line' => $exception->getLine()
        ]);
    }
    private function logError($type, $message, $file, $line) {
        $logMessage = date('Y-m-d H:i:s') . " [$type] $message in $file:$line" . PHP_EOL;
        error_log($logMessage, 3, __DIR__ . '/logs/error.log');
    }
    private function displayErrorPage($statusCode, $errorInfo) {
        http_response_code($statusCode);
        // 根据状态码选择不同的错误页面
        $errorPage = __DIR__ . '/error_pages/' . $statusCode . '.php';
        if (file_exists($errorPage)) {
            extract($errorInfo);
            include $errorPage;
        } else {
            // 默认错误页面
            echo "<h1>错误 {$statusCode}</h1>";
            echo "<p>{$errorInfo['message']}</p>";
        }
        exit;
    }
}
// 使用
$errorHandler = new ErrorHandler();
?>

错误页面示例(404.php)

<?php
// pages/errors/404.php
$title = "404 - 页面未找到";
?>
<!DOCTYPE html>
<html>
<head><?php echo $title; ?></title>
    <style>
        .error-container {
            text-align: center;
            padding: 50px;
            max-width: 600px;
            margin: 0 auto;
        }
        .error-code {
            font-size: 120px;
            color: #e74c3c;
            margin: 0;
        }
        .error-message {
            font-size: 24px;
            color: #333;
        }
        .back-home {
            display: inline-block;
            margin-top: 20px;
            padding: 10px 20px;
            background: #3498db;
            color: white;
            text-decoration: none;
            border-radius: 5px;
        }
    </style>
</head>
<body>
    <div class="error-container">
        <h1 class="error-code">404</h1>
        <p class="error-message">抱歉,您请求的页面不存在</p>
        <p>可能的原因:</p>
        <ul>
            <li>链接已经失效</li>
            <li>页面已被删除</li>
            <li>输入的网址有误</li>
        </ul>
        <a href="/" class="back-home">返回首页</a>
    </div>
</body>
</html>

最佳实践建议

  1. 开发环境:显示详细错误信息
  2. 生产环境:隐藏敏感信息,显示友好错误页面
  3. 日志记录:始终记录错误详情
  4. 分级处理:根据错误类型显示不同的错误页面
  5. 框架使用:如果使用框架(Laravel、Symfony等),通常有内置的错误处理机制

选择哪种方式取决于你的应用架构和需求,推荐组合使用 set_error_handler() 和 try-catch 来实现完整的错误处理。

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