伪静态不成功主因是服务器规则与框架配置未对齐:Apache需.htaccess+mod_rewrite+AllowOverride All三者同时生效;Nginx必须在server块写规则,并正确传递fastcgi_param PATH_INFO,否则PathInfo路由必404。
伪静态配不成功,90% 是服务器规则和框架配置没对齐,不是 ThinkPHP 本身的问题。
直接上关键点:Apache 要靠
+
+
三者同时生效;Nginx 必须在
块里写规则,且
要正确传递,否则
这类 PathInfo 路由必然 404。
Apache 下 .htaccess 规则为什么总不生效
常见错误是只放了规则,却忘了两件事:一是 Apache 没启用
,二是虚拟主机配置里
不是
。Linux 下用
启用模块后必须
(或
);Windows 下要手动在
里取消
的注释。然后检查对应
块里是否有
—— 如果是
或
,
里的
和
就会被忽略。
实际使用的
内容应为:
注意:
中的斜杠方向不能错;如果项目不在根目录(比如部署在
),必须加
,否则重写会跳到错误路径。
立即学习
“
PHP免费学习笔记(深入)
”;
Nginx 配置里 try_files 和 if 判断哪个更稳
看起来直观,但 Nginx 官方明确不推荐在
块中使用
,尤其搭配
时容易触发意外匹配(比如静态资源被误重写)。更可靠的是
方式:
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
它按顺序检查:先找真实文件 → 再找真实目录 → 最后 fallback 到
并把原始路径塞进
参数。这个写法兼容 TP5/TP6,默认路由模式下无需改框架代码。但要注意:如果你用了
设为
或其他符号,就得同步调整重写规则里的分隔逻辑,否则
这种写法会解析失败。
为什么 /index.
php
/index/index 能访问,但 /index/index 就 404
这是典型的 PathInfo 解析失败信号。Nginx 默认不自动拆解
后面的部分,必须显式告诉 PHP-FPM 怎么提取
。检查你的 Nginx 配置中处理 PHP 的
块里有没有这两行:
缺一不可。漏掉
,
就是空的;漏掉
,PHP 收不到
,ThinkPHP 自然无法路由。另外确认 PHP 配置中
(默认开启,但某些 Docker 镜像或安全加固环境会关掉)。
宝塔面板里选“ThinkPHP”伪静态规则却还是 404
宝塔内置的规则本质就是复制粘贴上面的 Nginx 片段,但它不会帮你检查三件事:
是否指向
目录、PHP 版本是否与 ThinkPHP 兼容(如 TP6.3 要求 PHP >=7.2)、以及站点配置里是否误启用了「防跨站攻击」导致
被截断。最简单的验证方式:临时在入口
开头加一行
,访问
,如果输出
或空字符串,问题一定出在 Nginx 的
传递环节,而不是规则本身。
真正卡住人的地方,从来不是规则怎么写,而是哪一层悄悄屏蔽了
—— 可能是 Nginx 配置、PHP 设置、宝塔开关,甚至 CDN 回源时把路径给抹了。逐层打日志比反复换规则更有效。
.htaccessmod_rewriteAllowOverride Allserverfastcgi_param PATH_INFOindex.php/控制器/方法mod_rewriteAllowOverrideAllsudo a2enmod rewritesudo systemctl restart apache2service apache2 restarthttpd.conf#LoadModule rewrite_module modules/mod_rewrite.soAllowOverride AllNoneFileInfo.htaccessRewriteCondRewriteRule.htaccessRewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]index.php/$1/myapp/RewriteBase /myapp/if (!-e $request_filename)locationifrewritetry_fileslocation / {
try_files $uri $uri/ /index.php?s=$uri&$args;
}index.phpspathinfo_depr'-'index.php/user-loginindex.php/xxxPATH_INFOlocation ~ \.php$fastcgi_split_path_info ^(.+\.php)(/.+)$;fastcgi_param PATH_INFO $fastcgi_path_info;fastcgi_split_path_info$fastcgi_path_infofastcgi_param$_SERVER['PATH_INFO']cgi.fix_pathinfo=1rootpublicPATH_INFOindex.phpvar_dump($_SERVER['PATH_INFO'] ?? 'MISSING');/index/indexMISSINGfastcgi_paramPATH_INFO