ThinkPHP在Nginx下伪静态核心是仅转发动态请求至public/index.php,优先用location ~*匹配静态后缀或目录直接由Nginx处理并缓存,再通过location /的try_files $uri $uri/ /index.php?$query_string安全转发,PHP块中必须用$realpath_root拼接SCRIPT_FILENAME,并确保框架开启url_route_on。

ThinkPHP在Nginx下配置伪静态,核心是让非静态资源的请求准确落到public/index.php,同时跳过真实存在的CSS、JS、图片等文件,不走PHP。关键不在“重写所有URL”,而在“只转发动态请求”。
静态资源必须提前拦截
Nginx按配置顺序匹配,静态规则要放在location /之前,否则每个.png都会进PHP,拖慢速度又浪费资源。
- 推荐用正则匹配常见后缀(不区分大小写):
location ~* \.(?:css|js|png|jpe?g|gif|webp|woff2?|ttf|eot|mp4|mp3|pdf)$ { expires 1y; add_header Cache-Control "public, immutable"; } - 如果静态文件统一放在
/public/static/目录,可单独拦截整个路径:location ^~ /static/ { alias /www/wwwroot/myapp/public/static/; expires 1y; add_header Cache-Control "public, immutable"; }
主路由交给try_files安全转发
确保root指向项目public/目录(不是项目根目录),然后在location /中写:
location / {
try_files $uri $uri/ /index.php?$query_string;
}这个规则的意思是:
立即学习“PHP免费学习笔记(深入)”;
- 先查
$uri是否对应真实文件(已被上面的静态规则拦住) - 再查
$uri/是否为真实目录 - 都不命中,才转给
/index.php?$query_string,TP8/6会自动解析路由
⚠️ 注意:$query_string保留全部GET参数,比s=更兼容、更稳定。
PHP处理块必须用$realpath_root
在location ~ \.php$块里,SCRIPT_FILENAME不能写成$document_root:
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
否则TP8会找不到自动加载文件,报Class 'think\App' not found却不提示原因。
ThinkPHP框架内也要配合开启
仅配Nginx不够,还要确认项目配置:
-
config/app.php中:'url_route_on' => true -
'url_html_suffix' => ''(空字符串,支持无后缀URL) - 若用PATH_INFO模式(如旧版TP5),还需
'pathinfo_depr' => '/'
验证方式:
- 访问
https://your.com/index.php/user/login能正常显示 → 入口OK - 访问
https://your.com/user/login也能正常响应,地址栏无index.php→ 伪静态生效
不复杂但容易忽略



















