如何设置phpEnv以启用PathInfo路径解析功能?
- 内容介绍
- 文章标签
- 相关推荐
本文共计647个文字,预计阅读时间需要3分钟。
《原创内容如下:
nginx location 块必须重写匹配逻辑
phpEnv 的默认 nginx 配置用的是 location ~ \.php$,这种写法会严格匹配以 .php 结尾的请求,根本不会把 /index.php/abc/def 这类路径交给 PHP 处理 —— 它直接 404 或返回静态文件。
你需要改成能捕获 pathinfo 的正则,并手动提取 SCRIPT_NAME 和 PATH_INFO:
- 把原配置中类似
location ~ \.php$ { ... }的块,替换成location ~ \.php(/|$) { ... } - 在该 block 内添加
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$; - 紧接着设置
fastcgi_param PATH_INFO $fastcgi_path_info;和fastcgi_param SCRIPT_NAME $fastcgi_script_name; - 务必确认
fastcgi_param SCRIPT_FILENAME指向的是真实 PHP 文件路径(如$document_root$fastcgi_script_name),不是拼出来的假路径
php.ini 必须开启 cgi.fix_pathinfo=1
即使 nginx 正确传了 PATH_INFO,PHP 本身也会在内部做一次路径截断。如果 cgi.fix_pathinfo 是 0 或注释状态,$_SERVER['PATH_INFO'] 就是空的,或者被截成乱码(尤其含中文时)。
立即学习“PHP免费学习笔记(深入)”;
操作步骤很简单但容易漏:
- 找到 phpEnv 当前启用的
php.ini(通常在/phpenv/etc/php/{version}/php.ini) - 搜索
cgi.fix_pathinfo,去掉前面的分号,改成cgi.fix_pathinfo = 1 - 如果找不到这行,就手动加在
[Global]区域末尾 - 改完必须重启 php-fpm:
phpenv fpm restart,光 reload 不生效
ThinkPHP 等框架里要验证 ORIG_PATH_INFO
nginx + phpEnv 组合下,遇到带中文或特殊符号的 pathinfo(比如 /index.php/文章/详情),$_SERVER['PATH_INFO'] 经常为空或乱码,但 $_SERVER['ORIG_PATH_INFO'] 是对的。
所以不要硬写 $_SERVER['PATH_INFO'],框架层要做 fallback:
- 先取
$_SERVER['PATH_INFO'] - 为空时再取
$_SERVER['ORIG_PATH_INFO'] - ThinkPHP 5+ 默认已处理这点,但自定义路由解析逻辑时得自己加判断
- 测试时用 curl 直接发请求,避免浏览器自动编码干扰:
curl "http://localhost/index.php/test/中文"
最容易被忽略的是:改完 nginx 配置后忘记 nginx -t && nginx -s reload,或者改了 php.ini 却没重启 php-fpm —— 这两个服务不重启,所有配置都是白改。
本文共计647个文字,预计阅读时间需要3分钟。
《原创内容如下:
nginx location 块必须重写匹配逻辑
phpEnv 的默认 nginx 配置用的是 location ~ \.php$,这种写法会严格匹配以 .php 结尾的请求,根本不会把 /index.php/abc/def 这类路径交给 PHP 处理 —— 它直接 404 或返回静态文件。
你需要改成能捕获 pathinfo 的正则,并手动提取 SCRIPT_NAME 和 PATH_INFO:
- 把原配置中类似
location ~ \.php$ { ... }的块,替换成location ~ \.php(/|$) { ... } - 在该 block 内添加
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$; - 紧接着设置
fastcgi_param PATH_INFO $fastcgi_path_info;和fastcgi_param SCRIPT_NAME $fastcgi_script_name; - 务必确认
fastcgi_param SCRIPT_FILENAME指向的是真实 PHP 文件路径(如$document_root$fastcgi_script_name),不是拼出来的假路径
php.ini 必须开启 cgi.fix_pathinfo=1
即使 nginx 正确传了 PATH_INFO,PHP 本身也会在内部做一次路径截断。如果 cgi.fix_pathinfo 是 0 或注释状态,$_SERVER['PATH_INFO'] 就是空的,或者被截成乱码(尤其含中文时)。
立即学习“PHP免费学习笔记(深入)”;
操作步骤很简单但容易漏:
- 找到 phpEnv 当前启用的
php.ini(通常在/phpenv/etc/php/{version}/php.ini) - 搜索
cgi.fix_pathinfo,去掉前面的分号,改成cgi.fix_pathinfo = 1 - 如果找不到这行,就手动加在
[Global]区域末尾 - 改完必须重启 php-fpm:
phpenv fpm restart,光 reload 不生效
ThinkPHP 等框架里要验证 ORIG_PATH_INFO
nginx + phpEnv 组合下,遇到带中文或特殊符号的 pathinfo(比如 /index.php/文章/详情),$_SERVER['PATH_INFO'] 经常为空或乱码,但 $_SERVER['ORIG_PATH_INFO'] 是对的。
所以不要硬写 $_SERVER['PATH_INFO'],框架层要做 fallback:
- 先取
$_SERVER['PATH_INFO'] - 为空时再取
$_SERVER['ORIG_PATH_INFO'] - ThinkPHP 5+ 默认已处理这点,但自定义路由解析逻辑时得自己加判断
- 测试时用 curl 直接发请求,避免浏览器自动编码干扰:
curl "http://localhost/index.php/test/中文"
最容易被忽略的是:改完 nginx 配置后忘记 nginx -t && nginx -s reload,或者改了 php.ini 却没重启 php-fpm —— 这两个服务不重启,所有配置都是白改。

