nginx配置pathinfo支持,最佳方案

〇. 前言

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.112 
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进程

原文地址:https://www.cnblogs.com/lihuobao/p/5286422.html