Yaf 框架优雅处理 404 页面:从基础配置到自定义实战

16次阅读
没有评论

Web 开发中,404 Not Found 页面是网站不可或缺的基础组件。一个友好的自定义 404 页面,不仅能提升用户体验,还能避免暴露框架底层报错信息,兼顾 SEO 与网站安全性。

Yaf 作为轻量、高性能的 PHP 框架,并没有内置可视化的 404 页面,而是通过异常机制处理未找到的请求(控制器 / 动作不存在)。本文将带你从零实现 Yaf 框架 404 页面的自定义,从基础配置到全局优雅处理,覆盖新手到进阶的全场景需求。


一、Yaf 默认的 404 响应(不推荐)

当用户访问不存在的控制器不存在的动作方法时,Yaf 会直接抛出 Yaf_Exception_NotFound 异常。

默认效果:

  1. 开发环境:直接输出异常堆栈信息,暴露框架路径、代码细节;
  2. 生产环境:空白页面或极简的Not Found文本,用户体验极差。

这显然无法满足生产环境需求,因此我们需要自定义 404 页面


二、核心原理

Yaf 处理 404 的核心逻辑:

请求无法匹配到合法的控制器 / 动作 → 抛出 Yaf_Exception_NotFound 异常 → 捕获该异常 → 转发到自定义的 404 页面

前置配置

首先修改 Yaf 的核心配置文件 conf/application.ini,开启异常抛出(必须配置):

ini

[common]
application.directory = APP_PATH "/application"
application.view.ext = "phtml"

; 👇 关键配置:开启异常抛出,允许我们手动捕获404
application.dispatcher.throwException = 1
; 关闭框架自动捕获异常(自定义处理时必选)
application.dispatcher.catchException = 0

[product : common]
; 生产环境关闭报错
display_errors = 0

三、基础实战:自定义 404 控制器 + 视图

这是最常用、最简单的实现方式,适合中小型项目。

步骤 1:创建 404 控制器

application/controllers/ 目录下,创建 Error.php 控制器(专门处理异常 / 404):

php

运行

<?php
/**
 * 异常控制器:处理404、系统错误
 */
class ErrorController extends Yaf_Controller_Abstract
{
    /**
     * 404页面动作
     */
    public function errorAction()
    {
        // ✅ 核心:设置HTTP 404状态码(SEO必须,否则搜索引擎视为正常页面)
        http_response_code(404);

        // 如果项目使用了布局模板,禁用布局(纯404页面)
        $this->_view->setLayout(false);

        // 可选:传递404提示信息到视图
        $this->_view->message = '您访问的页面不存在或已被删除';
    }
}

步骤 2:创建 404 视图模板

application/views/error/ 目录下,创建 error.phtml 视图文件:

html

预览

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>404 - 页面不存在</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { background: #f5f5f5; font-family: "Microsoft YaHei"; }
        .container {
            max-width: 600px;
            margin: 100px auto;
            text-align: center;
            padding: 40px 20px;
            background: #fff;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        h1 { font-size: 60px; color: #ff4d4f; margin-bottom: 20px; }
        p { font-size: 18px; color: #666; margin-bottom: 30px; }
        a {
            display: inline-block;
            padding: 10px 20px;
            background: #1890ff;
            color: #fff;
            border-radius: 4px;
            text-decoration: none;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>404</h1>
        <p><?= $this->message ?></p>
        <a href="/">返回首页</a>
    </div>
</body>
</html>

步骤 3:捕获 404 异常(入口文件)

修改项目入口文件 public/index.php,通过 try-catch 捕获 404 异常,并转发到我们的自定义页面:

php

运行

<?php
// 定义应用根目录
define('APP_PATH', dirname(__DIR__));
// 加载Yaf框架(根据你的项目自动加载配置调整)
require APP_PATH . '/vendor/autoload.php';

// 初始化Yaf应用
$app = new Yaf_Application(APP_PATH . '/conf/application.ini');

try {
    // 执行应用
    $app->run();
} catch (Yaf_Exception_NotFound $e) {
    // 👇 捕获404异常,转发到Error控制器的errorAction
    $dispatcher = Yaf_Dispatcher::getInstance();
    $dispatcher->dispatch(new Yaf_Request_Simple('HTTP', 'Error', 'error'));
} catch (Throwable $e) {
    // 其他异常处理(如系统错误)
    if (YAF_ENVIRON === 'product') {
        echo '服务器异常,请稍后重试';
    } else {
        var_dump($e->getMessage());
    }
}

测试:访问任意不存在的路由(如 /test/123),即可看到自定义的 404 页面!


四、进阶方案:Bootstrap 全局异常处理

大型项目推荐使用引导文件 (Bootstrap) 统一管理异常,这是 Yaf 官方推荐的规范写法,代码更优雅、易维护。

实现步骤

  1. 创建引导文件 application/Bootstrap.php

php

运行

<?php
class Bootstrap extends Yaf_Bootstrap_Abstract
{
    /**
     * 注册全局异常处理
     * @param Yaf_Dispatcher $dispatcher
     */
    public function _initException(Yaf_Dispatcher $dispatcher)
    {
        // 全局异常捕获函数
        set_exception_handler(function (Throwable $e) use ($dispatcher) {
            // 处理404异常
            if ($e instanceof Yaf_Exception_NotFound) {
                http_response_code(404);
                // 转发到404页面
                $dispatcher->setRequest(new Yaf_Request_Simple('HTTP', 'Error', 'error'));
                $dispatcher->dispatch();
                return;
            }

            // 其他异常处理逻辑
            if (YAF_ENVIRON === 'product') {
                exit('系统错误');
            }
            var_dump($e->getMessage());
        });
    }
}
  1. 简化入口文件:无需手动写try-catch,引导文件会自动接管异常处理:

php

运行

<?php
define('APP_PATH', dirname(__DIR__));
require APP_PATH . '/vendor/autoload.php';

$app = new Yaf_Application(APP_PATH . '/conf/application.ini');
$app->run(); // 直接运行即可

五、补充方案:路由兜底处理 404

除了异常捕获,还可以通过路由兜底实现 404:定义一个终极路由,匹配所有未被其他路由匹配的请求,直接转发到 404 页面。

Bootstrap.php 中添加路由配置:

php

运行

/**
 * 初始化兜底路由
 * @param Yaf_Dispatcher $dispatcher
 */
public function _initRoute(Yaf_Dispatcher $dispatcher)
{
    $router = $dispatcher->getRouter();
    // 正则路由:匹配所有请求(兜底路由,必须放在最后)
    $router->addRoute('404_fallback', new Yaf_Route_Regex(
        '#^(.*)$#',
        [
            'controller' => 'error',
            'action'     => 'error'
        ]
    ));
}

注意:兜底路由必须最后注册,否则会覆盖所有自定义路由!


六、关键注意事项

  1. 必须设置 404 状态码 一定要用 http_response_code(404),否则搜索引擎会将 404 页面判定为正常页面,影响 SEO。
  2. Linux 系统大小写问题 Yaf 在 Linux 下区分大小写,控制器名、视图目录名必须严格匹配(如ErrorController对应views/error/)。
  3. 生产环境屏蔽报错 生产环境务必关闭 display_errors,避免泄露服务器信息。
  4. 布局模板兼容 如果项目使用了全局布局,在 404 动作中用 $this->_view->setLayout(false) 禁用布局,保证页面纯净。

总结

Yaf 处理 404 页面的核心是捕获Yaf_Exception_NotFound异常,三种实现方案按需选择:

  1. 入门级:入口文件try-catch,简单快速;
  2. 进阶级:Bootstrap 全局异常处理,规范优雅,适合大型项目;
  3. 路由兜底:无异常捕获,纯路由实现,适合极简项目。

通过本文的方法,你可以快速为 Yaf 项目搭建一个美观、规范的 404 页面,完美兼顾用户体验与安全性。

正文完
可以使用微信扫码关注公众号(ID:xzluomor)
post-qrcode
 0
评论(没有评论)
验证码