Nginx不认ThinkPHP的Apache伪静态规则,因其不读.htaccess且无PT标志;需改写为Nginx原生配置,重点解决PATH_INFO传递、$args拼接及fastcgi_split_path_info正则匹配问题。

在 DigitalOcean 的 Ubuntu + Nginx 环境下,ThinkPHP 伪静态不能直接套用 Apache 的 .htaccess 规则,必须改写为 Nginx 原生 location + rewrite 配置,且需注意 PATH_INFO 兼容性问题。
为什么 Nginx 不认 ThinkPHP 的 Apache 伪静态规则
Nginx 根本不读 .htaccess 文件,所有重写逻辑必须写进 server 块;另外,ThinkPHP 默认依赖 index.php/xxx 这种 PATH_INFO 形式,而低版本 Nginx(如 1.18 及更早)默认不传递 PATH_INFO,会导致 $_SERVER['PATH_INFO'] 为空,路由全挂。
- Apache 的
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]在 Nginx 中没有等价的PT(pass-through)标志 -
QSA(query string append)需显式用$args拼接,否则 GET 参数会丢失 - 若用
last跳转但没配好fastcgi_split_path_info,PHP 就收不到路径段
Nginx 配置中必须写的三段关键代码
在你的站点 server 块里(比如 /etc/nginx/sites-available/your-site),把这三段粘进去,顺序不能错:
location / {
if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php?s=$1 last;
}
}
<p>location ~ .php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; # 根据你实际 PHP 版本调整
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_split_path_info ^(.+.php)(/.+)$;
}</p><p>location ~ /.ht {
deny all;
}- 第一段是兜底:所有非真实文件/目录的请求,都转给
/index.php?s=xxx—— 这是 ThinkPHP 官方兼容模式,不依赖 PATH_INFO - 第二段最关键:
fastcgi_split_path_info必须存在且正则匹配正确,否则$fastcgi_path_info为空,PATH_INFO就传不下去 - 第三段防暴露配置文件,安全必须项
ThinkPHP 端要同步改的两个配置项
光改 Nginx 不够,TP 框架得知道你在用哪种 URL 模式:
立即学习“PHP免费学习笔记(深入)”;
- 在
config/app.php(TP6)或Conf/config.php(TP3/5)里确认开启路由:'url_route_on' => true - 把 URL 模式设为兼容型:
'url_model' => 2(TP5/6)或define('URL_MODEL', 2)(TP3)—— 这样框架才会解析s=xxx参数而不是硬要 PATH_INFO - 如果用了
URL_HTML_SUFFIX(比如'.html'),确保 Nginx 的if (!-e ...)规则仍能命中,不要加额外后缀判断逻辑
验证和排错最常卡住的三个点
部署完 reload Nginx 后,打开页面报 404 或白屏,大概率是下面其中之一:
-
nginx -t报错:检查location ~ \.php$块是否漏了fastcgi_param SCRIPT_FILENAME,这个漏了就 502 - 首页能打开,但子路由 404:确认
url_model是2,不是1(PATH_INFO 模式);再检查fastcgi_split_path_info正则是否匹配你的入口路径(比如项目不在根目录,要改成^(.+\.php)(/.*)$) - GET 参数丢失(如
?id=123消失):rewrite 行末尾必须加?$args,完整写法是rewrite ^/(.*)$ /index.php?s=$1?$args last;
PATH_INFO 支持看似透明,实则极容易因 Nginx 版本、PHP-FPM 配置、TP 版本三者错位而静默失效——别信“配置完了就行”,每次换服务器环境都要重验 $_SERVER['PATH_INFO'] 和 $_GET['s'] 是否有值。



















