Nginx - 在其他目录和 PHP 中使用 root 的位置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40147326/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 02:07:47  来源:igfitidea点击:

Nginx - location with root in other directory and PHP

phpnginxnginx-location

提问by Akarun

I tried to set a location similar as "Apache Alias" with Nginx but I don't able to process PHP script in this folder.

我尝试使用 Nginx 设置一个类似于“Apache Alias”的位置,但我无法处理此文件夹中的 PHP 脚本。

Here is my folder structure (for Dev environment):

这是我的文件夹结构(用于开发环境):

/var/www
+-  dev/public/ <-- This is my normal Web root : "/"
|   +- assets/
|   |  +- app.css
|   |  +- app.js
|   |
|   +-  index.php
|   +-  favicon.png
|    
+-  cut/public/ <-- This must like an "Apache Alias" : "/cut"
    +- assets/
    |  +- app.css
    |  +- app.js
    |
    +-  index.php
    +-  other_other_file.php (why not)

I've tried different solutions but none of them are working.

我尝试了不同的解决方案,但都没有奏效。

Here is my best Nginx configuration :

这是我最好的 Nginx 配置:

server {
    listen   80;

    server_name _;
    root  /var/www/dev/public/;
    index index.php index.html;
    autoindex on;

    # Logs
    rewrite_log on;
    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;

    # Serving files
    location / {
        try_files $uri $uri/ @php;
    }

    location /cut {
        root /var/www/cut/public;
        try_files $uri $uri/ @php;
    }

    # PHP
    location @php {
        rewrite ^(.*)/?$ /index.php$is_args$args last;
    }

    location ~* \.php(/|$) {
        fastcgi_pass  php:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        fastcgi_param DOCUMENT_ROOT $document_root;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

With this one, all the content of my cut/public/folder is redirected to the dev/public/index.phpand interpreted (cause of try_file, I presume).

有了这个,我cut/public/文件夹的所有内容都被重定向到dev/public/index.php并解释(try_file我认为是因为 )。

That is why your help would be welcome.

这就是为什么欢迎您的帮助。

Final Solution

最终解决方案

After the answer of @richard-smith, here's the implemented solution :

在@richard-smith 的回答之后,这是实施的解决方案:

server {
    listen   80;

    server_name _;
    root  /var/www/dev/public/;
    index index.php index.html;

    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;

    location ^~ /cut {
        rewrite ^/cut/?(.*)$ /cut/public/ last;
    }

    location ^~ /cut/public {
        root /var/www/;
        try_files $uri $uri/ /cut/index.php$is_args$args;

        location ~* \.php(/|$) {
            fastcgi_pass  php:9000;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
            fastcgi_param DOCUMENT_ROOT $document_root;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    }

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~* \.php(/|$) {
        fastcgi_pass  php:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        fastcgi_param DOCUMENT_ROOT $document_root;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

回答by Richard Smith

Running two PHP applications side-by-side, you either need a common document root, or you need two location ~* \.php(or similar) blocks to ensure the correct SCRIPT_FILENAMEis sent to the fastcgi backend.

并排运行两个 PHP 应用程序,您要么需要一个公共文档根目录,要么需要两个location ~* \.php(或类似的)块以确保将正确SCRIPT_FILENAME的信息发送到 fastcgi 后端。

Use nested locationblocks to isolate the /cutsubdirectory, and use the ^~modifier at the top level to avoid other top level regular expression locationblocks from interfering (see this documentation).

使用嵌套location块来隔离/cut子目录,并^~在顶级使用修饰符来避免其他顶级正则表达式location块的干扰(请参阅此文档)。

The aliasdirective (see this documentation) is used to map /cutto /var/www/cut/public. The rootdirective can only concatenate, which would make /var/www/cut/public/cut(which you do not want).

alias指令(请参阅本文档)用于映射/cut/var/www/cut/public. 该root指令只能连接,这会使/var/www/cut/public/cut(您不想要)。

However, I would not recommend using the aliasdirective with the try_filesdirective because of this long term issue.

但是,由于这个长期问题,我不建议将alias指令与指令一起使用。try_files

So, a solution would be to silently rewrite /cutto /cut/publicand use a value of root /var/www.

所以,一个解决办法是悄悄改写/cut/cut/public和使用的价值root /var/www

For example:

例如:

location ^~ /cut {
    rewrite ^/cut(.*)$ /cut/public last;
}
location ^~ /cut/public {
    root /var/www;
    try_files $uri $uri/ /cut/index.php$is_args$args;

    location ~* \.php(/|$) {
        fastcgi_pass  php:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}