我在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;
}
Run Code Online (Sandbox Code Playgroud)
我使用PATH_INFO变量,因此我将以下行添加到fastcgi_params:
fastcgi_param PATH_INFO $fastcgi_path_info;
Run Code Online (Sandbox Code Playgroud)
在/etc/php5/fpm/php.ini中:
cgi.fix_pathinfo = 0
Run Code Online (Sandbox Code Playgroud)
我认为这应该有效,但是当我打印出所有服务器变量时,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',
.....
)
Run Code Online (Sandbox Code Playgroud)
我无法确定问题所在.有任何想法吗?
小智 6
我偶然发现了一个解决方案。该$fastcgi_path_info变种与一起工作$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;
}
Run Code Online (Sandbox Code Playgroud)
下的Nginx 文档中也有一个示例fastcgi_split_path_info。
(...我现在看到匹配上面的不止一篇文章。可能需要在 include 语句之后设置 PATH_INFO 行,以避免破坏值。)
首先,在现代 PHP 中,PATH_INFO存储在$_SERVER数组中。尝试:
echo "called SCRIPT_NAME: {$_SERVER['SCRIPT_NAME']} with PATH_INFO: {$_SERVER['PATH_INFO']}";
Run Code Online (Sandbox Code Playgroud)
无论如何,phpinfo()可以帮助找到很多内部 php 信息,比如变量和配置。
至于 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;
}
Run Code Online (Sandbox Code Playgroud)
将fastcgi_split_path_info您的位置分割为SCRIPT_NAME和PATH_INFO。
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
Run Code Online (Sandbox Code Playgroud)
正则表达式第一个括号中的表达式提取SCRIPT_NAME,而第二个括号中的表达式提取PATH_INFO。
第一个正则表达式组(.+?\.php)需要任何字符(点.),至少一次或多次(加号+)。带有尾随.php. 中的点.php被转义为\.php,因此它实际上不被视为“任何字符”。
问号?使加号变得惰性 ( +?),因此计算在第一个.php后缀处停止。
/some.php/next.php/path-info计算为a of ; 请注意,不要将 a of与 a of 搭配使用。SCRIPT_NAME/some.phpPATH_INFO/next.php/path-infoSCRIPT_NAME/some.php/next.phpPATH_INFO/path-info第二个正则表达式组(/.*)基本上将以斜杠开头的所有内容都视为PATH_INFO。
前导^和尾随$将表达式绑定到行的开头和结尾。
下一行检查提取的脚本是否确实作为文件存在:
try_files $fastcgi_script_name =404;
Run Code Online (Sandbox Code Playgroud)
否则返回404错误。这可以防止将不存在的文件提供给 PHP 处理器,但是有重置变量的坏习惯$fastcgi_path_info(请参阅: http: //trac.nginx.org/nginx/ticket/321)。
一种解决方法是将FCGI 参数存储并设置为存储$fastcgi_path_info的. 这是通过接下来的两行完成的:$path_info$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;
Run Code Online (Sandbox Code Playgroud)
然后在 的 include 中设置其他 FCGI 参数fastcgi.conf。该文件(有时也称为该文件)fastcgi_params应由您的发行版提供。
include fastcgi.conf;
Run Code Online (Sandbox Code Playgroud)
然后最后将请求传递到当前的 PHP 实例套接字(此处为 PHP 7.4):
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
Run Code Online (Sandbox Code Playgroud)
现在请记住,只有当周围的位置块被击中时,所有这一切才会发生。上面的示例是一个前缀位置,这意味着每个以前缀 开头的位置都匹配/main.php。这将是路由 PHP 应用程序的典型配置,该应用程序只有一个名为main.php. 要捕获所有.php文件,必须使用正则表达式,这可以像^.+?\.php(/|$). 之后(/|$)的.php意思是在该位置的部分之后要么有斜杠(以及更多字符)要么没有任何内容.php。子目录也是允许的,因此表达式基本上匹配包含 string 的每个位置.php,只要它位于末尾或后跟斜杠。
location ~ ^.+?\.php(/|$) {
#...
}
Run Code Online (Sandbox Code Playgroud)
由于该位置只是允许进入以下块的守卫,因此最终的 PHP 文件名和路径信息仍然按照上述方式进行分割。如果生成的文件名不存在,则返回 404。
这只是一个简单的配置。当然,配置位置正则表达式有多种可能性,以满足您特定应用程序的需求。要详细讨论所有这些细节将是一本小书。
我的工作配置如下:
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;
}
Run Code Online (Sandbox Code Playgroud)
尝试这个:
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
Run Code Online (Sandbox Code Playgroud)
http://wiki.nginx.org/PHPFcgiExample
http://trac.nginx.org/nginx/ticket/321
| 归档时间: |
|
| 查看次数: |
12254 次 |
| 最近记录: |