You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义PHP框架中实现自定义404错误页面的求助

自定义PHP框架中实现自定义404错误页面的求助

我最近在自己搭建的PHP MVC框架里开发项目,结果发现当访问不存在的路由时(比如plan/plan/views),框架直接抛出了一个未捕获的异常,页面上显示的是这样的致命错误信息:

Fatal error Uncaught exception: 'Exception' Message: 'No route matched.' Stack trace: #0 C:\xampp\htdocs\projects\wash\public\index.php(40): Core\Router->dispatch('plan/plan/views') #1 {main} Thrown in 'C:\xampp\htdocs\projects\wash\Core\Router.php' on line 130

这个信息在开发阶段排查问题还挺有用,但要是上线后给用户看到就太不友好了,我想改成显示自己设计的404页面,有没有懂行的大佬能给我指指路呀?


别担心,这个问题其实不难解决,咱们只需要在框架里把这个异常捕获并处理掉就行,具体步骤我给你整理好了:

  • 第一步:在入口文件捕获路由异常
    找到项目的入口文件public/index.php,就是调用Router->dispatch()的那个地方,把这段代码用try-catch块包起来。这样当路由匹配失败抛出异常时,咱们就能接管处理逻辑,不让系统直接输出错误堆栈。

修改后的index.php代码大概是这样的:

try {
    // 假设你是这样获取请求路由并分发的
    $requestedRoute = $_SERVER['REQUEST_URI'];
    $router = new Core\Router();
    $router->dispatch($requestedRoute);
} catch (Exception $e) {
    // 先判断是不是路由未匹配的异常
    if ($e->getMessage() === 'No route matched.') {
        // 先发送404的HTTP状态码,这很重要,搜索引擎能识别
        http_response_code(404);
        // 加载你自己写的404视图文件
        require_once '../views/errors/404.php';
    } else {
        // 如果是其他异常,比如服务器错误,就处理成500页面
        http_response_code(500);
        require_once '../views/errors/500.php';
        // 开发环境下可以临时输出异常详情方便调试,上线记得注释掉
        // echo "错误信息:" . $e->getMessage() . "<br>";
        // echo "错误文件:" . $e->getFile() . " 第" . $e->getLine() . "行";
    }
}
  • 第二步:制作自定义404视图页面
    在你的视图目录下新建一个errors文件夹,里面创建404.php,写一个友好的页面就行,比如:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>404 - 页面走丢啦</title>
    <style>
        .error-page {
            text-align: center;
            margin: 100px auto;
            max-width: 600px;
            font-family: '微软雅黑', sans-serif;
        }
        .error-code {
            font-size: 6rem;
            color: #ff4444;
            margin: 0;
        }
        .error-message {
            font-size: 1.5rem;
            color: #666;
            margin: 20px 0;
        }
        .back-home {
            display: inline-block;
            padding: 10px 20px;
            background: #007bff;
            color: white;
            text-decoration: none;
            border-radius: 5px;
            margin-top: 30px;
        }
        .back-home:hover {
            background: #0056b3;
        }
    </style>
</head>
<body>
    <div class="error-page">
        <h1 class="error-code">404</h1>
        <p class="error-message">哎呀,您访问的页面不存在或者已经搬家啦😥</p>
        <a href="/" class="back-home">返回首页</a>
    </div>
</body>
</html>
  • 第三步:优化异常判断(可选但推荐)
    如果想让代码更严谨,咱们可以自定义一个异常类,专门用来表示路由未找到的情况,这样就不用依赖错误信息的字符串来判断了。

比如在Core目录下创建Exceptions/RouteNotFoundException.php:

namespace Core\Exceptions;

class RouteNotFoundException extends \Exception {
    public function __construct($message = 'No route matched.', $code = 404, \Throwable $previous = null) {
        parent::__construct($message, $code, $previous);
    }
}

然后去Core/Router.php里找到抛出异常的地方,把原来的Exception改成咱们自定义的异常:

// 原来的代码
// throw new \Exception('No route matched.');
// 改成
throw new \Core\Exceptions\RouteNotFoundException();

这样在index.php的try-catch里就可以直接捕获这个特定的异常:

// 先捕获路由未找到的异常
catch (\Core\Exceptions\RouteNotFoundException $e) {
    http_response_code(404);
    require_once '../views/errors/404.php';
} catch (Exception $e) {
    // 处理其他所有异常
    http_response_code(500);
    require_once '../views/errors/500.php';
}

这样弄完之后,再访问不存在的路由,就能看到你自己设计的友好404页面啦,既专业又能提升用户体验~

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 13:34:53