nginx配置php伪静态需三者协同:一、root必须指向public目录;二、server块中location /内用if(!-e $request_filename){rewrite ^(.*)$ /index.php?s=$1 last;};三、框架启用url_route_on=true等路由参数。

Nginx 本身不支持 .htaccess,要让 PHP 项目(如 ThinkPHP、Laravel 或自建系统)实现伪静态(即隐藏 index.php、访问 /user/123 而非 /index.php/user/123),必须在 Nginx 配置中显式添加重写规则,并确保 PHP 处理流程能正确接收路由参数。
核心就三点:路径转发正确、入口文件可执行、框架能解析路由。缺一不可。
确保 root 指向 public 目录
这是最容易被忽略的前提。Nginx 的 root 必须指向项目的 public/(或 web/)目录,不是项目根目录。
例如:
root "/www/myapp/public";
如果指向错(比如指向 /www/myapp),/index.php?s=/user/list 会被拼成 /www/myapp/index.php,而实际入口在 /www/myapp/public/index.php,直接报 No input file specified 或 Primary script unknown。
同时确认 index 指令包含 index.php:
index index.php index.html;
选一种可靠的重写方式(推荐 if + rewrite)
Nginx 官方虽不推荐 if,但在 ThinkPHP、多数国产 PHP 框架及小皮/宝塔/phpEnv 等环境中,if (!-e $request_filename) 是最稳定、兼容性最强的写法。
在 server 块内、location ~ \.php$ 之前 添加:
location / {
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=$1 last;
}
}
注意:
-
last不可换成break或redirect;只有last会触发重写后重新匹配 location,让请求最终落到 PHP 处理块 -
s=$1是 ThinkPHP 默认路由参数名;Laravel 应用需改为s=$1或适配QUERY_STRING方式 - Windows 路径用正斜杠
/,如D:/www/app/public
补全 PHP 处理块的关键参数
光有重写不够,PHP 进程还得知道“到底该执行哪个文件”。检查 location ~ \.php$ 块是否包含:
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000; # 或 unix socket
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
特别注意:
-
SCRIPT_FILENAME必须用$document_root(不是$realpath_root或$root),它和上面的root指令联动 - 删除或注释掉
fastcgi_split_path_info相关行——它会干扰s=参数解析,尤其在 TP6/TP8 中易导致URL pathinfo not supported错误
框架层也要配合启用路由
Nginx 把请求转过去了,但框架若没开路由,照样走默认控制器。以 ThinkPHP 为例,确认 config/app.php 中:
-
url_route_on→true -
url_html_suffix→''(空字符串,否则只认/user/123.html) -
pathinfo_depr→'/'(和重写规则中s=$1的分隔逻辑一致)
Laravel 则需确保 APP_URL 正确、Route::get() 定义存在,且 .env 中 APP_ENV=local 或 production 下未禁用路由缓存。
验证顺序别乱
改完配置后:
- 先点「重载 Nginx」或运行
nginx -s reload - 访问
http://localhost/index.php/s=/index/hello,能出内容 → 说明 PHP 和入口正常 - 再访问
http://localhost/index/hello,能出内容 → 说明伪静态生效 - 若 404,查 Nginx 错误日志(如
logs/error.log),搜Primary script unknown或No input file specified,基本就是root或SCRIPT_FILENAME拼错了
不复杂但容易忽略。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











