ThinkPHP 6.x伪静态必须服务器重写规则、框架路由开关、Web根目录三者严格对齐:Apache需含PT/QSA的.htaccess及AllowOverride配置,Nginx须用try_files并禁用if,框架需开启url_route_on、pathinfo_depr匹配分隔符,且DocumentRoot必须指向public/。

ThinkPHP 6.x 伪静态没有“万能模板”,只有三处必须对齐:服务器重写规则、框架路由开关、Web 根目录指向。任一错位,必然 404 或白屏。
Apache 的 .htaccess 必须带 PT 和 QSA
常见错误是复制残缺规则,比如漏掉 PT 或 QSA,导致 $_SERVER['PATH_INFO'] 为空或参数丢失。
-
RewriteCond %{REQUEST_FILENAME} !-d和RewriteCond %{REQUEST_FILENAME} !-f缺一不可——否则/static/js/app.js这类真实文件会被错误转发到index.php -
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]中的/是分隔符,对应框架默认pathinfo_depr => '/';若你改过这个配置(比如设成-),这里就得同步改成index.php-$1 - 项目部署在子目录(如
/myapp/)时,RewriteBase /myapp/必须加,且RewriteRule目标要改为/myapp/index.php/$1 - Apache 虚拟主机配置里,
AllowOverride必须显式设为FileInfo Options,仅All在某些发行版下不生效
Nginx 必须用 try_files,禁用 if
if (!-e $request_filename) 是 Nginx 官方明确不推荐的写法,TP6 下极易引发 $_GET 丢失、POST 数据截断或白屏。
- 正确写法:
try_files $uri $uri/ /index.php?s=$uri&$args;—— 注意&是 HTML 实体,在配置文件中必须这样写,否则nginx -t会报错 - 不要用
rewrite ^/(.*)$ /index.php/$1 last;:TP6 默认不走 PATH_INFO 模式,/index.php/xxx访问方式已被弃用 -
location ~ \.php$块中,fastcgi_param SCRIPT_FILENAME必须指向$document_root/index.php(即public/index.php),不是项目根目录下的index.php - 宝塔面板选“ThinkPHP”伪静态模板时,默认用的是
if写法,上线前务必手动替换为try_files
框架层三个配置项不能关
光有服务器规则,config/app.php 里这三项没开,请求根本进不了路由层。
立即学习“PHP免费学习笔记(深入)”;
-
'url_route_on' => true:路由总开关,关了就全走默认控制器 -
'pathinfo_depr' => '/':必须和服务器规则里的分隔符一致(如 Apache 规则用了index.php/$1,这里就不能设成-) -
'url_common' => false:普通 URL 模式(?s=xxx)必须关闭,否则伪静态失效
Web 根目录必须是 public/
这是最容易被忽略的底层陷阱。TP6 的 autoload.php、think\App 类路径都基于 public/ 为起点计算,DocumentRoot 设错直接 Fatal Error。
- 宝塔新建站点时,默认 DocumentRoot 指向项目根目录(含
app/、config/),必须手动改为public/ - 检查
runtime/目录是否可写:伪静态只是让 URL 路由通了,但框架启动时要生成缓存,runtime/不可写会导致空白页 - 如果用
url()生成带后缀的 URL(如.shtml),Apache 需额外加AddHandler application/x-httpd-php .shtml,否则直接返回源码或 404
真正卡住的人,往往不是规则写错了,而是 Web 根目录没切到 public/,或者 url_route_on 还关着——这两处不动,其他全配对也白搭。



















