nginx+PHP 更好的办法实现PATH_INFO

in 前后端开发 with 0 comment

之前最初接触nginx配置的时候,我的PHP配置是这么写的

location ~* \.php(.*) {
    fastcgi_index        index.php;
    fastcgi_pass        unix:/run/php.sock;
    include            fastcgi_params;
    fastcgi_param        SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    fastcgi_param        SCRIPT_NAME        $fastcgi_script_name;
    fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;    
}

我们分析一下,用正则匹配含.php的路径,然后使用fastcgi_split_path_info 再次使用正则匹配PATH_INFO,如此就慢了很多
而且还有一种情况,那就是访问不存在的PHP文件,如 /not/exists.php/a/b/c ,这时候nginx还是交给了PHP-FPM处理,然后出现来自PHP-FPM返回的文件不存在的错误
于是我反思很久,花了很久研究出了新方法:

location ~* ^(.*\.php)(/.+)?$ {
    try_files        $1 =404;
    fastcgi_index        index.php;
    fastcgi_pass        unix:/run/php.sock;
    fastcgi_param SCRIPT_FILENAME   $document_root$1;
    fastcgi_param SCRIPT_NAME       $1;
    fastcgi_param PATH_INFO         $2;
    fastcgi_param QUERY_STRING      $query_string;
    fastcgi_param REQUEST_METHOD    $request_method;
    fastcgi_param REQUEST_URI       $request_uri;
    fastcgi_param CONTENT_TYPE      $content_type;
    fastcgi_param CONTENT_LENGTH    $content_length;
    fastcgi_param HTTPS             $https if_not_empty;
}

来,我们仔细看看,正则只有一条,第一个圆括号匹配PHP文件路径,第二个用于解析PATH_INFO,然后交给fastcgi_param,用最少的参数传递获得最高的吞吐能力
事实上,我们还使用try_files判断了文件是否存在,否则返回一个404,于是:

PHPINFO 成功

不存在

Responses