我在Debian上配置了nginx稳定(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',
.....
)我想不出问题出在哪里。有什么想法吗?
发布于 2018-03-13 08:04:34
我偶然发现了一个解决方案。$fastcgi_path_info变量与$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;
}在fastcgi_split_path_info下的Nginx documentation中也有一个示例。
(...我现在看到的匹配不止一个以上的帖子。(可能需要在include语句之后设置PATH_INFO行,以避免扰乱值。)
发布于 2018-02-17 14:26:57
我的工作配置如下:
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;
}发布于 2021-04-25 18:07:40
使用PHP进行调试
首先,在现代PHP中,PATH_INFO存储在$_SERVER数组中。尝试:
echo "called SCRIPT_NAME: {$_SERVER['SCRIPT_NAME']} with PATH_INFO: {$_SERVER['PATH_INFO']}";在任何情况下,phpinfo()都会帮助你找到大量的内部php信息,比如变量和配置。
Nginx配置
至于NginX的配置,大部分已经在其他帖子中解释过了。因此,这里是一个总结,并仔细查看以下示例位置块的详细信息和原因:
location /main.php {
# regex to split $uri to $fastcgi_script_name and $fastcgi_path_info
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后缀处停止。
- **E.g.** - `/some.php/next.php/path-info` is evaluated to a `SCRIPT_NAME` of `/some.php` with a `PATH_INFO` of `/next.php/path-info`; beware, not to a `SCRIPT_NAME` of `/some.php/next.php` with a `PATH_INFO` of `/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;结论
现在请记住,只有当周围的location块命中时,所有这些才会发生。上面的示例是一个前缀位置,这意味着每个位置都是匹配的,它以前缀/main.php开头。对于只有一个名为main.php的中心文件的路由应用程序来说,这是一种典型的配置。要捕获所有.php文件,必须使用正则表达式,它可以像^.+?\.php(/|$)一样简单。.php后面的(/|$)表示位置的.php部分后面要么有反斜杠(以及更多字符),要么什么都没有。子目录也是允许的,所以表达式基本上匹配包含字符串.php的每个位置,只要它在末尾或后面跟着一个斜杠。
location ~ ^.+?\.php(/|$) {
#...
}由于该位置只是允许进入下一块的守卫,因此最终的PHP文件名和路径信息仍然被如上所述地拆分。如果结果文件名不存在,则返回404。
这只是一个简单的配置。当然,有很多种方法可以配置位置正则表达式,以满足特定应用程序的需要。要深入了解所有这些细节,只需一本小书。
https://stackoverflow.com/questions/20848899
复制相似问题