Nginx 中 ThinkPHP 伪静态需在 location / 内用 if (!-e $request_filename) 判断后 rewrite ^/(.*)$ /index.php?s=$1&$args last,并独立配置 location ~ \.php$ 块,根目录指向 public/ 且开启路由。

rewrite ^/(.*)$ /index.php?s=$1 这类规则在 Nginx 中确实能实现 ThinkPHP 的伪静态转发,但直接放在 location / 外或配置不当,极易出错。它不是万能写法,关键在于「在哪写、怎么写、配合什么」。
必须写在 location / 块内部,且用 if 判断兜底
Nginx 不支持在 server 块顶层直接写 rewrite(除非加 break 或用于重定向),而 ThinkPHP 要求的是「非真实文件请求全部交给 index.php 处理」。所以标准做法是:
location / {
index index.php;
if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php?s=$1 last;
}
}-
!-e $request_filename:判断请求路径是否对应真实存在的文件或目录 -
^/(.*)$:捕获完整 URI(不含域名和参数),如/user/login→$1就是user/login -
last:重写后重新匹配 location,确保能进入后续的location ~ \.php$块执行 PHP - 不用
break(会终止重写链,PHP 不执行);不用redirect(变成 302 跳转,暴露 index.php)
⚠️ 注意:
if在 Nginx 官方文档中标记为“应避免使用”,但在宝塔、小皮等面板 + ThinkPHP6 场景下,它仍是兼容性最强、最不容易 500 的方案,比try_files更容错(尤其当root配置有偏差时)。
必须搭配 location ~ \.php$,且顺序不能错
上面的 rewrite 只是把 /user/list 变成 /index.php?s=user/list,真正执行 PHP 的,是下面这个块:
立即学习“PHP免费学习笔记(深入)”;
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
}- 这个块必须放在
location /之后、但不能被它包裹(即独立同级) - 如果写在
location /内部,Nginx 会忽略(正则 location 不能嵌套在普通 location 里) - 如果写在
location /之前,可能因匹配优先级问题导致 rewrite 不触发
参数传递要完整:s=$1 不够,建议补上 &$args
ThinkPHP 路由参数(如 /user/view?id=123)里的 $_GET['id'] 要能取到,$args(即原始 query string)必须显式拼接:
✅ 推荐写法:
rewrite ^/(.*)$ /index.php?s=$1&$args last;
❌ 错误写法(丢参数):
rewrite ^/(.*)$ /index.php?s=$1 last; # $_GET 为空
子目录部署需改写路径前缀
比如项目访问地址是 https://site.com/shop/,那么:
-
rewrite目标不能是/index.php,而应是/shop/index.php - 正则也要排除前缀,避免重复匹配:
location /shop/ {
if (!-e $request_filename) {
rewrite ^/shop/(.*)$ /shop/index.php?s=$1&$args last;
}
}同时确保 location ~ \.php$ 能正确匹配 /shop/index.php —— 更稳妥的做法是单独配一个 PHP location:
location ~ ^/shop/(.+\.php)$ {
alias /var/www/html/shop/public/$1;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}补充两个关键确认点
- ✅ 网站根目录必须指向 ThinkPHP 的
public/目录(不是项目根目录) - ✅ ThinkPHP 配置中开启路由:
'url_route_on' => true,'pathinfo_depr' => '/','url_html_suffix' => ''
不复杂但容易忽略。



















