推荐方法 - 通过 app.php 配置文件(最简单)
这是 ThinkPHP 官方推荐且最简单的方法,通过在应用的全局配置文件中指定 404 页面的路径即可。

(图片来源网络,侵删)
适用场景
- 当你的 404 页面是一个静态的 HTML 文件时,这是最佳选择。
- 当你希望所有类型的 404 错误(如控制器不存在、方法不存在、路由不存在)都指向同一个页面时。
操作步骤
-
创建 404 模板文件 在你的项目
public目录下(或其他 Web 服务器可访问的目录),创建一个 HTML 文件作为你的 404 页面。在
public目录下创建html文件:<!-- 文件路径: /public/404.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> body { font-family: 'Arial', sans-serif; background-color: #f4f4f4; color: #333; text-align: center; padding-top: 50px; } .container { max-width: 600px; margin: 0 auto; background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); } h1 { color: #e74c3c; } p { font-size: 18px; line-height: 1.6; } a { color: #3498db; text-decoration: none; font-weight: bold; } a:hover { text-decoration: underline; } </style> </head> <body> <div class="container"> <h1>哎呀!404 了</h1> <p>抱歉,您访问的页面不存在或已被移除。</p> <p>请检查您输入的网址是否正确,或者 <a href="/">点击这里返回首页</a>。</p> </div> </body> </html> -
修改应用配置文件 打开你的应用配置文件
app.php,它通常位于app/应用名/config/app.php路径下。在该文件中,找到
http_exception_template配置项,并将其值设置为你刚刚创建的 404 模板的路径。
(图片来源网络,侵删)// 文件路径: app/应用名/config/app.php return [ // ... 其他配置项 ... // 将这个配置项修改为你的 404 模板路径 'http_exception_template' => [ // 404 错误对应的模板 404 => app()->getRootPath() . 'public/404.html', // 你也可以自定义其他状态码的模板 // 500 => app()->getRootPath() . 'public/500.html', // 403 => app()->getRootPath() . 'public/403.html', ], // ... 其他配置项 ... ];说明:
app()->getRootPath()会获取到项目的根目录(即public目录的上一级),所以拼接public/404.html就能准确定位到文件。- 这个配置项是一个数组,你可以为不同的 HTTP 状态码(如 403, 500)指定不同的模板。
-
测试 重启你的 PHP 服务器(如果需要),然后访问一个不存在的 URL(
http://你的域名/一个不存在的页面),你就会看到自定义的 404 页面了。
备用方法 - 通过路由捕获
这种方法更灵活,可以让你在控制器中处理 404 逻辑,例如记录日志、动态渲染模板等。
适用场景
- 当你的 404 页面需要动态数据时(从数据库获取内容)。
- 当你需要在 404 页面中执行一些额外的逻辑(如记录错误日志)。
- 当你想区分不同原因导致的 404(如路由不存在 vs 控制器不存在)。
操作步骤
-
在路由文件中定义 404 路由 在你的
app/应用名/route/目录下,打开app.php(或根据你的route.php配置)路由文件,添加一个通配符路由来捕获所有未匹配的请求。
(图片来源网络,侵删)// 文件路径: app/应用名/route/app.php use think\facade\Route; // ... 其他路由定义 ... // 定义一个 404 页面路由 // '*' 会匹配所有未定义的路由 Route::any('*', 'Error/notFound'); -
创建错误控制器 创建一个名为
Error的控制器,并编写notFound方法来处理 404 逻辑。// 文件路径: app/应用名/controller/Error.php <?php declare (strict_types = 1); namespace app\controller; use think\Request; use think\Response; use think\facade\View; class Error { /** * 处理 404 错误 * @param Request $request * @return Response */ public function notFound(Request $request): Response { // 1. 记录日志(可选) // trace('404 Not Found: ' . $request->url(), 'error'); // 2. 渲染模板 // 可以直接返回一个字符串,或者使用视图引擎 // 方法 A: 直接返回字符串 // return response('<h1>页面不存在</h1><p>请检查您的URL。</p>', 404); // 方法 B: 使用视图引擎渲染模板(推荐) // 假设你的模板在 view/error/404.html View::assign([ 'message' => '您访问的页面不存在哦!', 'url' => $request->url(), ]); return response(View::fetch('error/404'), 404); } } -
创建视图模板 在
app/应用名/view/目录下创建error目录,并在其中创建html文件。<!-- 文件路径: app/应用名/view/error/404.html --> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>动态 404 页面</title> <style> body { font-family: 'Microsoft YaHei', sans-serif; background-color: #fafafa; text-align: center; padding-top: 100px; } h1 { color: #ff6b6b; } p { color: #666; } </style> </head> <body> <h1>404 - 页面未找到</h1> <p>您请求的路径是: <strong>{$url}</strong></p> <p>{$message}</p> <p><a href="/">返回首页</a></p> </body> </html> -
测试 访问一个不存在的 URL,系统会自动跳转到
Error/notFound方法,并渲染你自定义的动态 404 模板。
总结与对比
| 特性 | 方法一(配置文件) | 方法二(路由) |
|---|---|---|
| 实现难度 | 非常简单,只需配置一个路径。 | 稍微复杂,需要创建控制器和视图。 |
| 灵活性 | 较低,只能指向静态文件。 | 非常高,可以处理动态数据、执行业务逻辑。 |
| 性能 | 性能更好,直接返回静态文件,不经过 PHP 框架解析。 | 性能稍差,因为请求需要经过路由和控制器。 |
| 适用场景 | 简单的、静态的 404 页面。 | 需要动态内容或复杂逻辑的 404 页面。 |
推荐建议:
- 对于绝大多数项目,使用方法一(配置文件) 是最佳选择,它简单、高效、且官方支持良好。
- 只有当你确实需要在 404 页面中展示动态内容或执行额外操作时,才考虑使用方法二(路由)。
