我刚开始接触到互联网时大都用的是Apache(用虚拟主机搭博客),后来工作了发现公司都是用的Nginx,Nginx的牛逼之处就不bb了,显而易见。
后来使用Nginx搭建博客,配置伪静态(PATH_INFO)时,如果请求的是 /xxx.php 就会报 File not found. 如果是 /xxxx 就正常,带了php结尾就不行。这个问题困扰了我很长时间,一直不得解。
这次重装系统,在网上找资料加上反复动手实验,终于解决了,正确配置如下。
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php$1 last;
break;
}
location ~ \.php(.*)$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_split_path_info ^((?U).+\.php)(.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
include fastcgi_params;
}
PS:
if 的优先级比 location 高,放 location 前后面都行,大致逻辑是判断请求的 path 既不是文件也不是目录,就重写到 /index.php/xxx 去解析。
fastcgi_split_path_info 的正则主要是匹配2个参数,一个是 $fastcgi_script_name 执行文件名, $fastcgi_path_info 匹配 PATH_INFO。
关于正则网上有 ^(.+\.php)(.+)$
^(.+\.php)(/?.+)$
^((?U).+\.php)(.+)$
的写法,经过测试带 (?U)
要正确些(不带也不报错)。
如URL /a.php/cccc,如果带了 (?U)
那么执行文件名则拿到 /index.php,PATH_INFO 拿到的是/a.php/cccc (应当请求的 PATH 为 PATH_INFO 才对,所以这里要正确些)。否则执行文件名拿到的是 /index.php/a.php,PATH_INFO 拿到的是 /cccc,建议动手实验一下就清楚了(配置上方规则,不带 (?U)
,新建 index.php,内容为 <?php var_dump($_SERVER);
请求 /a.php/ccc 看 $_SERVER 打印的 PATH_INFO 和 PHP_SELF 就清楚了)。
- Prev: Redis GEO 在 Laravel 框架中的使用
- Next: Nginx 不带www跳转到带www