ThinkPHP 如何配置 Nginx 伪静态规则避免首页 404 错误?

文章导读
90% 的 ThinkPHP6 控制器 404 问题源于 Nginx 的 PathInfo 支持未正确配置,需在 location / 块中添加 rewrite 规则将非静态请求转发至/public/index.php。
📋 目录
  1. A 原因分析
  2. B 解决方案
  3. C 争议方案对比
  4. D 注意事项
  5. E 参考来源
A A

ThinkPHP 如何配置 Nginx 伪静态规则避免首页 404 错误?

核心结论:90% 的 ThinkPHP6 控制器 404 问题源于 Nginx 的 PathInfo 支持未正确配置,需在 location / 块中添加 rewrite 规则将非静态请求转发至/public/index.php。

原因分析

ThinkPHP6 默认使用 PathInfo 模式识别路由,URL 结构如/index.php/blog/show。但 Nginx 默认不认识这种格式,会把整个路径当作真实文件路径去查找。当访问/hello/dwy时,Nginx 返回404 Not Found nginx/1.23.3,而访问根路径却能正常返回内容。

根本原因不是 ThinkPHP 配置错了,是 Nginx 根本没把请求交给 index.php 处理——location 块没兜住除静态资源外的所有请求。宝塔内置的"ThinkPHP"伪静态模板默认适配的是 ThinkPHP 5.0–5.1 的 URL 模式 (index.php?s=/home/index/index),而 TP6 默认启用 pathinfo 且入口在 public 目录,预设规则没匹配上真实请求路径。

解决方案

步骤一:确认 Nginx 配置位置

找到对应的 Nginx 站点配置文件,通常位于/etc/nginx/sites-available//usr/local/nginx/conf/vhost/目录下。在 server 块内、location ~ \.php$之前插入以下规则:

location / {
    if (!-e $request_filename) {
        rewrite ^(.*)$ /public/index.php?s=$1 last;
    }
}

注意:/public/index.php是关键,TP6 默认把入口放在 public/子目录。必须插在location ~ \.php$之前,否则 PHP 匹配优先级更高,if 不触发。用last,不是breakredirectlast让 Nginx 重走 location 匹配流程。

步骤二:设置运行目录为/public

宝塔面板中需进入:网站 → 设置 → 网站目录 → 运行目录,下拉选择/public(不是留空,也不是/)。TP6 要求 Web 服务器 DocumentRoot 必须是 public/,否则 vendor/autoload.php 加载路径错乱,直接 Fatal Error。

步骤三:确保 PATH_INFO 透传

在站点配置的location ~ \.php$块内,确认包含以下两行:

fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;

部分宝塔版本生成的规则末尾用了break,导致重写后不再重新匹配 location,/index.php?s=xxx被当成静态文件返回 404。

ThinkPHP 如何配置 Nginx 伪静态规则避免首页 404 错误?

步骤四:验证配置生效

修改配置后执行nginx -t验证语法是否正常,若输出"syntax is ok",继续执行nginx -s reload。若提示"test is failed",说明规则中存在语法错误,需返回配置文件手动修正。

争议方案对比

方案 A:使用 if + rewrite

if (!-e $request_filename) {
    rewrite ^(.*)$ /public/index.php?s=$1 last;
}

适用场景:宝塔面板 + TP6 环境,兼容性最好。

方案 B:使用 try_files

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

注意:在宝塔 + TP6 场景下,try_files $uri $uri/ /public/index.php?$query_string会导致$_GET['s']为空,路由全挂。此方案更适合 Laravel 等框架。

注意事项

1. 路由强制模式检查:确认 config/app.php 中'url_route_must' => true是否开启,否则 404 可能被 URL 解析绕过,压根进不了路由判断。

2. 避免通配路由吞掉请求:确保没有在 route/app.php 里写死一个通配路由 (如Route::any('[:all]', )) 吞掉了所有未匹配请求。

ThinkPHP 如何配置 Nginx 伪静态规则避免首页 404 错误?

3. 404 兜底路由配置:在 route/app.php 底部添加Route::miss(function() { return response()->view('public/404', [], 404); });,必须放在所有 Route::get/Route::post 等规则之后。

4. Nginx 不要拦截 404:检查 Nginx 配置中是否写了error_page 404 /404.html;这类语句,删掉或注释,否则 ThinkPHP 的 404 是 PHP 层返回的,但 Nginx 会直接返回自己的 404 页面,PHP 根本没机会执行。

5. 快速验证方法:在 URL 里显式加上 index.php,如http://yoursite.com/index.php/blog/show,如果能正常访问,那基本可以确定是 PathInfo 解析问题。运行命令php think route:list确认路由确实已经注册。

参考来源

来源:技术社区 - ThinkPHP6(TP6) 控制器 404 问题排查与 Nginx 伪静态配置指南(2026 年 4 月 1 日)

来源:运维论坛 - 宝塔面板如何配置 ThinkPHP 6 伪静态_解决页面访问提示 404 错误(2026 年 4 月 20 日)

来源:开发者博客 - 解决 ThinkPHP 访问路由 404:Nginx 伪静态配置指南(2025 年 9 月 2 日)

来源:技术文档 - ThinkPHP 怎么处理 404 错误_ThinkPHP 自定义 404 页面设置(2026 年 4 月 15 日)