繁体   English   中英

Nginx + phpFPM:PATH_INFO 始终为空

[英]Nginx + phpFPM: PATH_INFO always empty

我在 Debian 上配置了 nginx stable (1.4.4) + PHP(使用 FastCGI、php-fpm)。 这工作正常:

     location ~* ^/~(.+?)(/.*\.php)$ {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        alias /home/$1/public_html$2;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        fastcgi_index index.php;
        autoindex on;
     }

我使用 PATH_INFO 变量,因此我在 fastcgi_params 中添加了以下行:

fastcgi_param   PATH_INFO       $fastcgi_path_info;

在 /etc/php5/fpm/php.ini 中:

cgi.fix_pathinfo = 0

我认为这应该可行,但是当我打印出所有服务器变量时,PATH_INFO 始终为空:

    array (
  'USER' => 'www-data',
  'HOME' => '/var/www',
  'FCGI_ROLE' => 'RESPONDER',
  'QUERY_STRING' => '',
  'REQUEST_METHOD' => 'GET',
  'CONTENT_TYPE' => '',
  'CONTENT_LENGTH' => '',
  'SCRIPT_FILENAME' => '/usr/share/nginx/html/srv_var.php',
  'SCRIPT_NAME' => '/srv_var.php',
  'PATH_INFO' => '',
  'REQUEST_URI' => '/srv_var.php',
  'DOCUMENT_URI' => '/srv_var.php',
  'DOCUMENT_ROOT' => '/usr/share/nginx/html',
  'SERVER_PROTOCOL' => 'HTTP/1.1',
  'GATEWAY_INTERFACE' => 'CGI/1.1',
  'SERVER_SOFTWARE' => 'nginx/1.4.4',
  .....
)

我想不出问题出在哪里。 有什么想法吗?

我偶然发现了一个解决方案。 $fastcgi_path_info var 与$fastcgi_split_path_info一起使用,需要在 location 块中设置。 以下是在我们的环境中起作用的内容:

location ~ [^/]\.php(/|$) {
    root /var/www/jurism-php;
    if (!-f $document_root$fastcgi_script_name) {
        return 404;
    }
    # Mitigate https://httpoxy.org/ vulnerabilities
    fastcgi_param HTTP_PROXY "";
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    include fastcgi_params;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
}

Nginx 文档中的fastcgi_split_path_info下也有一个示例。

(...我现在看到匹配上面的多个帖子。可能需要在 include 语句之后设置 PATH_INFO 行,以避免破坏该值。)

我的工作配置如下:

location ~ [^/]\.php(/|$) {
    fastcgi_split_path_info ^(.+\.php)($|/.*);
    try_files $fastcgi_script_name =404;

    set $path_info $fastcgi_path_info;
    fastcgi_param PATH_INFO $path_info;

    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index  index.php;  
    include fastcgi_params;    
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_ignore_client_abort off;
}

对于人们来到这里,阅读的东西..

问题似乎是正则表达式(regex)在

location ~* ^/~(.+?)(/.*\.php)$ {

永远不会匹配不以 .php 结尾的 uri,因此另一个正则表达式永远不会“捕获”最后一个捕获组中的任何内容。

    fastcgi_split_path_info ^(.+?\.php)(/.*)$;

因此,将第一个正则表达式更改为以下内容将“修复”该问题。

location ~ [^/]\.php(/|$) {

试试这个:

set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;

http://wiki.nginx.org/PHPFcgiExample

http://trac.nginx.org/nginx/ticket/321

迟到的答案,但它可能对某人有用。

我使用了变量 REQUEST_URI 而不是 PATH_INFO。 看起来它包含与 PATH_INFO 应该具有的值相同的值。

这是我得到的。 它就像一个魅力。

  • nginx 1.10.1
  • php 5.6.24

https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/

我遇到过这个问题,但我的情况略有不同,因为我在指令中使用了try_files 这是我的配置以及技术说明:

这是我的location块的样子

location / {
    include         php-fpm.conf;
    try_files       $uri $uri/ /index.php =404;
}

php-fpm.conf

fastcgi_pass                127.0.0.1:9000;
fastcgi_index               index.php;
fastcgi_split_path_info     ^(.+?\.php)(/.+)$;
fastcgi_param               PATH_INFO       $fastcgi_path_info;
set $path_info              $fastcgi_path_info;
include                     fastcgi.conf;
fastcgi_param               PATH_INFO $path_info;

这里有两个特别的通知:

  • 我通过brew安装了nginx ,但它包含PATH_INFO参数,所以我必须手动添加它(取自此处
fastcgi_param   PATH_INFO               $fastcgi_path_info;
  • 使用try_files是一种特殊情况(来源
The ​try_files directive changes URI of a request to the one matched on the file system, and subsequent attempt to split the URI into $fastcgi_script_name and $fastcgi_path_info results in empty path info - as there is no path info in the URI after try_files.
  • 所以我们要做的是将INFO_PATH保存到一个临时变量,然后使用该临时变量设置INFO_PATH

首先,在现代 PHP 中, PATH_INFO存储在$_SERVER数组中。 尝试:

echo "called SCRIPT_NAME: {$_SERVER['SCRIPT_NAME']} with PATH_INFO: {$_SERVER['PATH_INFO']}";

在任何情况下, phpinfo()都会帮助找到很多内部 php 信息,比如变量和配置。

至于 NginX 配置,大部分已经在其他帖子中进行了解释。 所以这是一个总结,并仔细研究了以下示例位置块的细节和原因:

location /main.php {
  # regex to split $uri to $fastcgi_script_name and $fastcgi_path
  fastcgi_split_path_info ^(.+?\.php)(/.*)$;

  # Check that the PHP script exists before passing it
  try_files $fastcgi_script_name =404;

  # Bypass the fact that try_files resets $fastcgi_path_info
  # see: http://trac.nginx.org/nginx/ticket/321
  set $path_info $fastcgi_path_info;
  fastcgi_param PATH_INFO $path_info;

  # set the standard fcgi paramters
  include fastcgi.conf;

  # pass the request to the socket
  fastcgi_pass unix:/run/php/php7.4-fpm.sock;
}

fastcgi_split_path_infoSCRIPT_NAMEPATH_INFO之间拆分您的位置。

fastcgi_split_path_info ^(.+?\.php)(/.*)$;

第一个括号中的表达式提取SCRIPT_NAME第二个PATH_INFO 所以(.+?\\.php)需要任何字符(点. ),至少一次或多次(加号+ )。 带有尾随.php .php的点被转义为\\.php因此从字面上看,它不是“任何字符”。

问号? 使加号变得懒惰( +? ),因此评估在第一个.php后缀处停止。 所以/some.php/next.php/path-info进行评估,以一个SCRIPT_NAME/some.phpPATH_INFO/next.php/path-info ,而不是一个SCRIPT_NAME/some.php/next.php/path-infoPATH_INFO

第二个表达式基本上将所有以斜杠开头的内容作为PATH_INFO

前导^和尾随$将表达式绑定到行的开头和结尾。

下一行检查提取的脚本是否确实作为文件存在:

try_files $fastcgi_script_name =404;

否则返回404错误。 这可以防止将不存在的文件提供给 PHP 处理器,但是有重置$fastcgi_path_info变量的坏习惯(请参阅: http : //trac.nginx.org/nginx/ticket/321 )。 一种解决方法是将$fastcgi_path_info存储在$path_info ,并将 FCGI 参数设置为存储的$path_info 这是由接下来的两行完成的:

# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;

然后在fastcgi.conf的 include 中设置其他 FCGI 参数。 这个文件,有时也被命名为fastcgi_params应该由你的发行版提供。

include fastcgi.conf;

然后最后将请求传递给您当前的 PHP 实例套接字(此处为 PHP 7.4):

fastcgi_pass unix:/run/php/php7.4-fpm.sock;

现在请记住,所有这一切只会发生,如果周围的位置块被击中 上面的例子是一个前缀位置,意味着每个位置都匹配,以前缀/main.php 这将是路由 PHP 应用程序的典型配置,该应用程序只有一个名为main.php中央文件。 要捕获所有.php文件,必须使用正则表达式,这可能像^.+?\\.php(/|$)一样简单。 .php后面的(/|$)表示该位置的.php部分后面有一个反斜杠(和更多字符)或什么都没有。 也允许使用子目录,因此表达式基本上匹配包含字符串.php每个位置,只要它位于末尾或后跟斜杠即可。

location ~ ^.+?\.php(/|$) {
  #...
}

由于位置只是允许进入以下块的守卫,因此最终的 PHP 文件名和路径信息仍按上述方式拆分。 如果生成的文件名不存在,则返回 404。 这只是一个简单的配置。 当然,配置位置正则表达式有无数种可能性,以满足您特定应用程序的需求。 要深入了解所有这些细节将是一本小书。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM