yii框架怎么自定义错误页面_yii框架404和500错误页面美化配置【方法】

Yii 应用里 404 页面不显示自定义内容,只看到空白或默认 Nginx 页

根本原因是 Nginx 或 Apache 拦截了 404,根本没把请求交给 Yii 处理。Yii 的错误页面(如 site/error)只有在框架内部抛出 yii\web\NotFoundHttpException 时才会触发;如果 Web 服务器自己判定路径不存在并直接返回 404,Yii 压根不知道发生了什么。

解决方法分两层:

确保 Web 服务器把所有非静态资源请求都转给 index.php(Nginx 用 try_files $uri $uri/ /index.php?$args;,Apache 用 .htaccess 中的 RewriteRule)确认 Yii 的 urlManager 已启用美化:enablePrettyUrl => true,否则 /post/123 这类路径进不来,直接被 Web 服务器判为 404检查 config/web.php 中是否配置了 ‘errorHandler’ => [‘errorAction’ => ‘site/error’] —— 缺这项,即使 Yii 抛出异常,也会回落到 PHP 默认错误页

为什么设置了 site/error,但 404 页面里拿不到 $exception->statusCode

因为 $exception 变量只在由 Yii 主动抛出异常时才完整可用。比如用户访问 /nonexistent,而该路由未定义,Yii 会抛 NotFoundHttpException,这时 $exception->statusCode 是 404;但如果控制器里手动写了 throw new \Exception(‘xxx’),它就不是 HTTP 异常,statusCode 为 0。

更常见的情况是:你期望显示 404,但实际渲染的是 500 页面。这是因为 site/error.php 视图本身出错(比如调用了不存在的 helper 方法),导致二次异常,最终 fallback 到最简错误页。

调试建议:

在 views/site/error.php 开头加 <?php var_dump($exception ?? null); die; ?> 看实际传入对象确认 $exception 是 yii\web\HttpException 子类,才能安全调用 getStatusCode()避免在 error 视图中使用未初始化的组件或依赖 layout 中可能失败的 asset bundle

Nginx 层面也想加一层兜底 404 页面,和 Yii 的怎么共存

可以共存,但必须明确分工:Nginx 的 error_page 404 /404.html 只处理「连 index.php 都没匹配到的请求」,比如直接访问 /favicon.ico 不存在、或 /css/missing.css 找不到;而 Yii 的 site/error 负责处理「请求进了 PHP,但路由/权限/逻辑层面失败」的场景。

关键点:

Nginx 的 error_page 必须放在 location / 块之外(通常在 server 块顶层),否则会被子 location 覆盖确保你的静态资源 location(如 location ~* \.(js|css|png|jpg)$)**不带** try_files 或 fastcgi_pass,否则会错误地把 404 请求也转给 PHPYii 生成的 URL(如 Url::to([‘post/view’, ‘id’ => 1]))必须基于正确配置的 urlManager,否则前端发出去的请求本身就带 index.php,绕过美化规则,导致 Nginx 直接 404

自定义 500 页面时,Ajax 请求返回 HTML 而不是 JSON

Yii 默认对 Ajax 请求也渲染 HTML 错误页,这会导致前端 JS 解析失败。必须显式判断请求类型并切换响应格式。

最稳妥的做法是在 config/web.php 中重写 errorHandler 的 errorAction,或者继承 yii\web\ErrorHandler 并覆盖 renderException。但简单项目可直接在 site/error 视图开头加判断:

if (Yii::$app->request->getIsAjax()) { Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; echo json_encode([ ‘code’ => $exception->getCode(), ‘message’ => $exception->getMessage(), ]); exit;}

注意:$exception->getCode() 对 HTTP 异常(如 404、500)返回的是状态码;对普通 Exception 返回 0,需按需映射。

容易忽略的一点:如果用了自定义 ErrorAsset 或在 error 视图里加载了 JS/CSS,而这些资源路径又因美化配置错误返回 404,就会引发嵌套错误,让整个错误处理链失效。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。