如何从NGiNX fastcgi_script_name中删除路径段?

时间:2015-12-30 05:13:05

标签: php regex nginx

这个问题也可能是:“如何使用RegEx修改NGiNX变量?”, 或者:“RegEx反向引用可以有差距吗?”

其中任何一个都可以解决我遇到的问题。也许存在一个非常简单的解决方案,在挖掘网络几个小时后,是时候寻求帮助了。

以下是该方案:

请求URI的一部分将始终存在(对于某种花哨的域名+ URI组合:-)。我强制存在那个始终存在的URI路径组件,紧跟在域名之后,如下所示:

http://somedomain.com/basepart/rest/of/the/path?q=123

在上面的示例中,“/ basepart”表示始终存在的URI组件。

到目前为止一切顺利。当我希望基本文件路径为/var/www/somedomain.com/htdocs/而不使用basepart时,会出现问题,并使用php5_fpm代理。我显然设定了:

    location /basepart {
            alias /var/www/somedomain.com/htdocs;
            try_files $uri $uri/ /index.php?$args;
    }

但由于动态文件是PHP格式,我需要使用fastcgi_split_path_info$request_uri来构建/传递SCRIPT_FILENAME到php5_fpm。我怎么做?如何从/basepart$fastcgi_script_name删除$request_uri,否则PHP会在/var/www/somedomain.com/htdocs/basepart中查找该文件?

我考虑过命名反向引用,或“收集”或“碎片化”反向引用(我认为它不存在于正则表达式中),以便我可以在$fastcgi_script_name之前和之后捕获fastcgi_split_path_info中的段{ {1}}分配发生了,但没有让它们起作用。 Dayo writes earlier at SO:»Nginx是一个网络服务器而不是脚本应用程序。»,并建议使用Lua进行更复杂的脚本编写。但我有一种感觉,我可能会忽略一些非常简单,有价值的解决方案: - ]。

任何想法,任何人?

2 个答案:

答案 0 :(得分:2)

alias指令适用于静态网站,但在涉及PHP时则不太有用。我首选的解决方案是在不使用/basepart的情况下在内部重写URI,然后使用root而不是alias

问题是许多PHP脚本使用$request_uri来处理请求,该请求在/basepart完整时被冻结。但是,我们可以指定我们为REQUEST_URI选择的任何值,并从$uri构建更合适的值或捕获。在下面的示例中,我在第一次重写后保留$uri的值,以便可以将它用于将修改后的请求URI 传递给PHP脚本。

root /var/www/somedomain.com/htdocs;

location ^~ /basepart {
    rewrite ^/basepart/(.*)$ /$1 last;
    rewrite ^ / last;
}

location / {
    internal;
    try_files $uri @index;
}

location @index {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root/index.php;
    fastcgi_param REQUEST_URI $uri;
    ...
}

location ~ \.php$ {
    internal;
    try_files $uri @index;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param REQUEST_URI $uri;
    ...
}

fastcgi代码块跨两个位置重复。如果它变得笨拙,可以将公共代码放入单独的包含文件中。

使用internal指令将位置设为私有,保持/basepart必须进行外部访问。

答案 1 :(得分:0)

如果有人偶然发现了这个问题,经过一番集思广益,我想出了一个显而易见的解决方案:

    root /app/frontend/web/;
    location /api/ {
        alias /app/backend/web/;
        index index.php index.html;
        # Double /api/ because "that's how nginx alias and try_files works together"
        try_files $uri /api//api/index.php$is_args$args;

        location ~ ^/api(/.*\.php(?:\?.*)?)$ {
            try_files $uri /api//api/index.php$is_args$args;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$1;
            ...
        }
    }

即使用正则表达式捕获组。

使用此规则,请求将通过以下方式进行路由:

  /index.html -> /app/frontend/web/index.html
  /test/test.php -> /app/frontend/web/test/test.php as plaintext
  /api/<somepath> -> /app/backend/web/<somepath> (proxied to FPM if .php) if it exists, otherwise /app/backend/web/index.php