〇. 前言
pathinfo有两个,1 pathinfo()函数,2 $_SERVER['PATH_INFO']。
pathinfo()是php的库函数,原生支持不需要nginx配置,$_SERVER['PATH_INFO']才需要nginx的特殊配置。
为什么要配置pathinfo,因为ThinkPHP/CodeIgniter/Yii等MVC框架都需要$_SERVER['PATH_INFO']。
一. 配置pathinfo支持之前,先让nginx支持PHP
这里有个缺陷,就是得到的SCRIPT_NAME不准确。
二. 开始配置 pathinfo
这是传统的nginx - pathinfo 解决方案
三. 寻找最佳方案的途中
因为配置文件里面PATH_INFO 跟 SCRIPT_NAME 都是使用了 $fastcgi_script_name,所以strace追踪nginx进程发现两者一样是正常的。可是从浏览器请求的效果看到PATH_INFO跟SCRIPT_NAME却不一样,虽然从最终结果看,它符合我们的要求,可是不合理呀。
我猜想,是php-fpm或者说fastcgi对此做了一些容错处理。
四. 最佳方案
五. rewrite 隐藏index.php
另外,现在nginx官方推荐使用try_files取代rewrite,不过try_files好像不支持正则,有兴趣的童鞋自行研究哈。给出一个例子,如下
六. 附件
1) 上面用到的配置文件的合集
1 server { 2 listen 80; 3 server_name test; 4 charset utf-8; 5 6 index index.html index.htm index.php; 7 root /var/www/test; 8 9 # rewrite 隐藏index.php 10 location / { 11 if (!-e $request_filename){ 12 rewrite ^/(.*)$ /index.php/$1 last; 13 break; 14 } 15 } 16 17 # 传统方案 18 #location ~ \.php { 19 # set $real_script_name $path_info; 20 # 21 # if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") { 22 # set $real_script_name $1; 23 # set $path_info $2; 24 # } 25 # 26 # include fastcgi_params; 27 # fastcgi_param SCRIPT_FILENAME $document_root$real_script_name; 28 # fastcgi_param PATH_INFO $path_info; 29 # fastcgi_param SCRIPT_NAME $real_script_name; 30 # 31 # fastcgi_pass 127.0.0.1:9000; 32 #} 33 34 # 寻找最佳方案的途中 35 #location ~ \.php { 36 # include fastcgi.conf; 37 # fastcgi_param PATH_INFO $fastcgi_script_name; 38 # 39 # fastcgi_pass 127.0.0.1:9000; 40 #} 41 42 # 最佳方案 43 location ~ \.php { 44 fastcgi_split_path_info ^(.+\.php)(/.+)$; 45 46 include fastcgi.conf; 47 fastcgi_param PATH_INFO $fastcgi_path_info; 48 49 fastcgi_pass 127.0.0.1:9000; 50 } 51 52 }
2) fastcgi.conf 的中文注释
1 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #脚本文件请求的路径 2 fastcgi_param QUERY_STRING $query_string; #请求的参数;如?app=123 3 fastcgi_param REQUEST_METHOD $request_method; #请求的动作(GET,POST) 4 fastcgi_param CONTENT_TYPE $content_type; #请求头中的Content-Type字段 5 fastcgi_param CONTENT_LENGTH $content_length; #请求头中的Content-length字段。 6 7 fastcgi_param SCRIPT_NAME $fastcgi_script_name; #脚本名称 8 fastcgi_param REQUEST_URI $request_uri; #请求的地址 9 fastcgi_param DOCUMENT_URI $document_uri; #与$uri相同。 10 fastcgi_param DOCUMENT_ROOT $document_root; #网站的根目录。在server配置中root指令中指定的值 11 fastcgi_param SERVER_PROTOCOL $server_protocol; #请求使用的协议,通常是HTTP/1.0或HTTP/1.1。 12 13 fastcgi_param GATEWAY_INTERFACE CGI/1.1; #cgi 版本 14 fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; #nginx 版本号,可修改、隐藏 15 16 fastcgi_param REMOTE_ADDR $remote_addr; #客户端IP 17 fastcgi_param REMOTE_PORT $remote_port; #客户端端口 18 fastcgi_param SERVER_ADDR $server_addr; #服务器IP地址 19 fastcgi_param SERVER_PORT $server_port; #服务器端口 20 fastcgi_param SERVER_NAME $server_name; #服务器名,域名在server配置中指定的server_name 21 22 # PHP only, required if PHP was built with --enable-force-cgi-redirect 23 fastcgi_param REDIRECT_STATUS 200; 24 25 在php可打印出上面的服务环境变量 26 如:echo $_SERVER['REMOTE_ADDR']
3) nginx 的uri、request_uri 区别
$request_uri: /stat.php/qw/cv?id=1585378&web_id=1585378
$uri /stat.php/qw/cv
$document_uri: /stat.php/qw/cv
3) 检验 REQUEST_URI / DOCUMENT_URI / PHP_SELF / PATH_INFO
echo 'REQUEST_URI - '.$_SERVER['REQUEST_URI'];
echo '<br />DOCUMENT_URI - '.$_SERVER['DOCUMENT_URI'];
echo '<br />SCRIPT_NAME - '.$_SERVER['SCRIPT_NAME'];
echo '<br />PHP_SELF - '.$_SERVER['PHP_SELF'];
echo '<br />PATH_INFO - '.$_SERVER['PATH_INFO'];
同时strace 追踪nginx进程