必须用try_files而非if重写:location / { try_files $uri $uri/ /index.php?$query_string; },因tp6默认关闭pathinfo且入口仅支持request_uri解析,$query_string确保参数不丢失,且需将webroot设为public目录、runtime可写并禁用自定义request_uri覆盖。

ThinkPHP 6 的 Nginx 伪静态规则必须用 try_files
宝塔或手动配置 Nginx 时,很多人照搬旧版规则写 if (!-e $request_filename) { rewrite ^/(.*)$ /index.php/$1 last; },结果首页能打开、其他路由全白屏。这不是 ThinkPHP 问题,是 Nginx 规则本身在 PHP-FPM 环境下不兼容 —— $1 会把路径拼进 PATH_INFO,但 TP6 默认关闭 pathinfo 模式,且入口文件 public/index.php 不再支持 /index.php/xxx 这种访问方式。
正确做法是用 try_files,让 Nginx 直接把请求交给 index.php 并透传原始 URI:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
关键点:
-
try_files不依赖PATH_INFO,TP6 的路由解析完全基于$_SERVER['REQUEST_URI'] - 必须保留
$query_string,否则带参数的 URL(如/user?id=1)会丢参 - 不要加
last或break,try_files内部已处理跳转逻辑 - 确认
fastcgi_param SCRIPT_FILENAME指向的是public/index.php,不是项目根目录下的index.php
Apache 的 .htaccess 必须启用 mod_rewrite 且不能被覆盖
白屏常发生在本地开发正常、上线就空白,大概率是 Apache 没真正启用重写模块,或站点配置里禁用了 .htaccess 解析。
检查项:
- 运行
a2enmod rewrite并重启 Apache,确认模块已加载 - 在虚拟主机配置中,
<directory></directory>块内必须有AllowOverride All,否则.htaccess被忽略 - ThinkPHP 官方
.htaccess内容应为标准格式,不能删减或改写成 Laravel 风格 - 若用宝塔,「伪静态」下拉菜单必须选
thinkphp,而不是留空或选错模板
错误示例:RewriteRule ^(.*)$ index.php [L] 缺少 QSA 标志,会导致查询参数丢失,部分路由匹配失败后静默返回空响应。
伪静态生效但 still 白屏?先排除 runtime 和入口路径双重陷阱
即使重写规则完全正确,白屏仍可能发生,因为两个底层条件没满足:
-
public/目录没设为 Web 根目录:宝塔新建站点默认指向项目根(含app/、config/),但 TP6 要求 Web 服务器 DocumentRoot 必须是public/;否则vendor/autoload.php加载路径错乱,think\App类找不到,直接 Fatal Error -
runtime/不可写:伪静态只是让 URL 路由通了,但框架启动时要生成缓存和日志。若runtime/权限不对(比如属主是root,而 PHP 进程以www运行),框架初始化失败,无任何错误输出 - 别用
chmod -R 755整个项目:这会让config/和app/可被 Web 访问,存在泄露风险;只执行chmod -R 775 runtime+chown -R www:www runtime
为什么加了伪静态还是 404 或白屏?检查 fastcgi_param 是否覆盖了 REQUEST_URI
Nginx + PHP-FPM 下,如果白屏同时伴随 500 错误或日志里出现 Undefined index: REQUEST_URI,说明 PHP 接收到的原始请求路径被篡改了。
常见原因:
- 站点配置里误加了
fastcgi_param REQUEST_URI $uri;—— 这会把重写前的路径(如/user)塞给 PHP,但 TP6 需要的是完整原始 URI(含查询参数) - 正确写法是删掉所有自定义
REQUEST_URI设置,依赖 PHP-FPM 默认行为,或显式写成fastcgi_param REQUEST_URI $request_uri;(注意是$request_uri,不是$uri) - 宝塔用户可在「网站 → 设置 → 配置文件」里搜索
REQUEST_URI,删掉冗余行
这个点极容易被忽略:规则看着对,权限看着对,调试也开了,但就差这一行参数,导致整个路由系统收不到真实请求路径,最终静默失败。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











