我在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',
.....
)
我无法确定问题所在。有什么想法吗?
答案 0 :(得分:3)
我偶然发现了一个解决方案。 $fastcgi_path_info
var与$fastcgi_split_path_info
一起使用,需要在位置块中设置。这是在我们的环境中起作用的:
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;
}
fastcgi_split_path_info
下的Nginx documentation还有一个示例。
(...我现在看到匹配上面的多个帖子。可能需要在include语句之后设置PATH_INFO行,以避免破坏该值。)
答案 1 :(得分:1)
试试这个:
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
答案 2 :(得分:1)
我的工作配置如下:
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;
}
答案 3 :(得分:1)
对于到这里来的人,阅读东西。
问题似乎是其中的正则表达式(regex)
location ~* ^/~(.+?)(/.*\.php)$ {
将永远不会匹配不以.php结尾的uri,因此另一个正则表达式将永远不会“捕获”最后一个捕获组中的任何内容。
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
因此,将第一个正则表达式更改为以下内容将“修复”该问题。
location ~ [^/]\.php(/|$) {
答案 4 :(得分:0)
迟到的答案但对某人可能有用。
我使用变量REQUEST_URI而不是PATH_INFO。看起来它包含与PATH_INFO应具有的相同的值。
答案 5 :(得分:0)
这是我得到的。它就像一个魅力。
https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/
答案 6 :(得分:0)
我遇到过这个问题,但我的情况略有不同,因为我在指令中使用了 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;
这里有两个特别通知:
nginx
安装了 brew
并且它不包含 PATH_INFO
参数,所以我不得不手动添加它(取自 here) fastcgi_param PATH_INFO $fastcgi_path_info;
try_files
是一种特殊情况 (source)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
答案 7 :(得分:0)
首先,在现代 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_info
将您的位置在 SCRIPT_NAME
和 PATH_INFO
之间分开。
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
第一个括号中的表达式提取 SCRIPT_NAME
第二个 PATH_INFO
。所以 (.+?\.php)
需要任何字符(点 .
),至少一次或多次(加号 +
)。带有尾随 .php
。 .php
中的点被转义为 \.php
,因此从字面上看不是“任何字符”。
问号 ?
使加号懒惰 (+?
),因此计算在第一个 .php
后缀处停止。所以 /some.php/next.php/path-info
被评估为 SCRIPT_NAME
的 /some.php
和 PATH_INFO
的 /next.php/path-info
而不是 SCRIPT_NAME
的 /some.php/next.php
和PATH_INFO
的 /path-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
的包含中设置其他 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。这只是一个简单的配置。当然,配置位置正则表达式有无数种可能性,以满足您特定应用程序的需求。要深入了解所有这些细节将是一本小书。