必须用try_files,因其按序检查静态文件/目录后交由/index.php?$query_string处理,不依赖PATH_INFO、避免白屏和循环重定向,且兼容TP5/6/8,默认路由模式。

try_files 更好,是 ThinkPHP 在 Nginx 下的推荐方案。
它更轻量、更安全、更符合 Nginx 设计哲学,而 rewrite 容易出错、开销更高,尤其在 ThinkPHP 场景中属于非必要复杂化。
try_files 为什么更适合 ThinkPHP
- 直接按顺序检查文件或目录是否存在,命中即返回,不触发正则解析、不重建 URI、不引发 location 重匹配
- 静态资源优先:真实图片、CSS、JS 被直接服务;不存在时才交由 index.php 处理,天然防误伤
- 无 if 块,彻底规避 Nginx 官方明确指出的反模式(如
if (!-e $request_filename)),避免 PATH_INFO 为空、白屏、循环重定向等问题 - 支持
$query_string透传,GET 参数不丢失;配合$realpath_root可确保 ThinkPHP 6/8 类自动加载正常 - 启用
open_file_cache后,文件存在性检查还能被缓存,进一步降低 I/O
典型配置:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
rewrite 在 ThinkPHP 中的问题较多
- 依赖 PCRE 正则引擎,每次请求都要匹配、捕获、替换,CPU 开销明显更高(实测延迟高 10%–25%)
- 容易写错:比如漏掉
&$args导致 GET 参数丢失,或用/index.php/$1却没配fastcgi_split_path_info,导致$_SERVER['PATH_INFO']为空 -
if + rewrite组合在 PHP 8.5+ 和 Windows 下兼容性差,ThinkPHP 6/8 默认已转向 querystring 模式,没必要强走 PATH_INFO - 多条 rewrite 串联或嵌套在 if 中,会显著放大性能损耗,Nginx 文档明确建议避免
常见但不推荐的写法:
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=$1 last;
}
实际部署关键点
- ✅ root 必须指向
public/目录,否则框架类找不到,页面静默空白 - ✅ PHP 处理块中必须用
$realpath_root而非$document_root:fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
- ✅ 若需保留 PATH_INFO(如旧版 TP5.1),则
location ~ \.php$内必须配:fastcgi_split_path_info ^(.+\.php)(/.*)$; fastcgi_param PATH_INFO $fastcgi_path_info;
- ✅ 子目录部署(如
/myapp/)时,try_files 的兜底路径要同步调整:location /myapp/ { try_files $uri $uri/ /myapp/index.php?$query_string; }
不复杂但容易忽略。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











