ThinkPHP部署Nginx核心是入口路径、路由转发、PHP执行链路三者严丝合缝;root必须指向public目录,用try_files替代if判断,fastcgi_param SCRIPT_FILENAME需与fastcgi_pass严格匹配,PATH_INFO仅旧版按需启用。

ThinkPHP部署到Nginx服务器,核心不是“照搬配置”,而是让入口路径、路由转发、PHP执行链路三者严丝合缝。多数报错(如404、空白页、PATH_INFO错乱、文件找不到)都源于其中一环断开。下面按实际部署逻辑分步说明。
一、确认项目结构与Web根目录指向
ThinkPHP 5/6/8 默认采用 public 目录为唯一 Web 入口,index.php 必须被 Nginx 直接访问。这是所有配置的前提:
-
root 必须指向 public 目录,例如:
root /var/www/myapp/public;—— ✅ 正确 - 若 root 指向项目根目录(如
/var/www/myapp),则需用alias替代,但极易出错,不推荐 - 检查 Nginx 用户(如 www-data 或 nginx)对
public/及其上级目录有可执行(x)权限,否则无法遍历路径
二、基础伪静态规则:用 try_files 替代 if 判断
网上大量配置还在用 if (!-e $request_filename) + rewrite,这在 Nginx 中属于反模式,易引发重写循环或静默失败。应统一使用 try_files:
- 放在
location /块内: try_files $uri $uri/ /index.php?$query_string;- 含义:先找真实静态文件 → 再找目录 → 最后交由 index.php 处理,并透传全部查询参数
- 注意:结尾是
/index.php?$query_string,不是/index.php/$1;ThinkPHP 8 默认走 querystring 模式,无需 PATH_INFO
三、PHP 请求处理:fastcgi_pass 与 SCRIPT_FILENAME 必须匹配
这是部署卡住最频繁的环节。PHP 脚本能否真正执行,取决于 fastcgi_pass 是否连通、SCRIPT_FILENAME 是否拼出真实路径:
立即学习“PHP免费学习笔记(深入)”;
-
fastcgi_pass 要与 php-fpm 实际监听方式一致:
– Unix socket:fastcgi_pass unix:/run/php/php8.1-fpm.sock;(注意unix:前缀不能漏)
– TCP:fastcgi_pass 127.0.0.1:9000;(别写 localhost,DNS 解析可能拖慢) -
SCRIPT_FILENAME 推荐用:
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
比$document_root$fastcgi_script_name更健壮,能自动解析软链接 - 确保
include fastcgi_params;在该 location 块中已加载,且未被重复覆盖
四、按需启用 PATH_INFO(仅旧版或特殊需求)
除非你明确设置了 URL_MODEL = 1(PATHINFO 模式),或兼容 TP3.2 等老项目,否则无需开启 PATH_INFO。若必须启用:
- 在 PHP location 块中添加:
fastcgi_split_path_info ^(.+\.php)(/.+)$; - 并设置两个关键参数:
fastcgi_param PATH_INFO $fastcgi_path_info;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - 注意:不要同时启用 PATH_INFO 和 querystring 模式,会冲突
配置完成后,运行 sudo nginx -t 检查语法,再 sudo systemctl reload nginx 生效。访问首页若仍报错,优先查看 Nginx error log(通常在 /var/log/nginx/error.log),错误信息往往直指哪一环没对上。



















