伪静态由nginx(或apache)在请求到达php前完成url重写,php仅接收重写后的request_uri或path_info;关键依赖cgi.fix_pathinfo=1、fastcgi_split_path_info正则正确截取、rewrite规则触发时机准确。

phpenv 本身不处理伪静态 —— 它只是 PHP 版本管理工具(类似 pyenv 或 rbenv),不涉及 Web 服务器配置。你真正要配的是 Nginx,而 phpenv 管理的 PHP 是通过 PHP-FPM 被 Nginx 调用的。
所以问题本质是:在使用 phpenv 切换 PHP 版本的前提下,如何给 Nginx 正确配置 Rewrite 规则以支持 PHP 项目的伪静态(如 ThinkPHP、Laravel 或自定义路由)?
为什么改了 php.ini 或 phpenv 切换版本后伪静态失效?
常见错觉是“PHP 控制伪静态”,其实不是。伪静态由 Nginx(或 Apache)在请求到达 PHP 前就完成了 URL 重写;PHP 只负责接收重写后的 $_SERVER['REQUEST_URI'] 或 $_SERVER['PATH_INFO']。
但有一个关键依赖:
- 若项目依赖
PATH_INFO(比如 ThinkPHP 的index.php/xxx/yyy模式),需确保:- Nginx 的
fastcgi_param PATH_INFO正确截取 - PHP 配置中
cgi.fix_pathinfo=1(默认开启,但某些phpenv安装可能覆盖为 0)
- Nginx 的
检查方式:
php -i | grep 'cgi.fix_pathinfo'如果输出是
cgi.fix_pathinfo => 0 => 0,就得手动改当前 PHP 版本的 php.ini(路径通常为 $(phpenv root)/versions/$(phpenv version-name)/etc/php.ini),设为:
cgi.fix_pathinfo=1然后重启 PHP-FPM(或你的本地服务)。
Nginx location + rewrite 必须匹配 PHP-FPM 处理逻辑
很多失败源于 location ~ .php$ 和主 location / 的规则冲突。典型错误配置:
location / {
rewrite ^/(.*)$ /index.php/$1 last; # ✅ 重写进来了
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
# ❌ 缺少 PATH_INFO 解析,导致 $_SERVER['PATH_INFO'] 为空
}
正确做法(以 ThinkPHP 为例):
- 用
try_files更安全(推荐):
location / {
try_files $uri $uri/ /index.php?s=$uri&args;
}
- 或显式用
rewrite+ 正确传递PATH_INFO:
location / {
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=$1 last;
}
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param QUERY_STRING $query_string;
include fastcgi_params;
}
注意:fastcgi_split_path_info 这一行不能少,否则 $fastcgi_path_info 为空,PATH_INFO 就传不进去。
宝塔 / 本地开发环境常见坑:rewrite.conf 被忽略
你写了 rewrite.conf 并 include rewrite.conf;,但没生效?检查三点:
-
include语句是否写在正确的location /块内(而不是 server 块顶层)?
✅ 正确位置:location / { include /path/to/rewrite.conf; # 其他指令... }❌ 错误位置(server 块下直接 include):Nginx 不允许在 server 级 userewrite指令,会报"rewrite" directive is not allowed here rewrite.conf文件权限是否可读?Nginx worker 进程用户(如www-data或nobody)必须有读取权限修改后是否执行了
nginx -t && nginx -s reload?宝塔用户点「保存」会自动 reload,但 CLI 手动改必须自己 reload
伪静态真正的复杂点不在规则写法,而在 Nginx 如何把原始 URI 安全、无歧义地拆解并传递给 PHP。PATH_INFO 截取错一位、fastcgi_split_path_info 正则没兜住、cgi.fix_pathinfo=0 关闭 —— 任一环节断掉,$_SERVER['PATH_INFO'] 就为空,框架路由就 404。动手前先确认这三处:PHP 配置、Nginx PATH_INFO 截取、rewrite 触发时机。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











