配置 nginx 以与多个 PHP 前端控制器协同工作

配置 nginx 以与多个 PHP 前端控制器协同工作

我目前正在尝试将一个 PHP 应用程序从每页 php 文件转换为基于前端控制器的系统,从运行 Apache 的服务器迁移到 Nginx。该站点在子文件夹中还有几个其他 PHP 应用程序,它们使用自己的前端控制器,但不断遇到 try_files 问题,要么无法用于某些不再存在的文件的旧 URL,要么根目录 try_files 会覆盖子文件夹 try_files。

例如:

/section.php/123/1/slugtext 的请求应作为 /front.php/section.php/123/1/slugtext 发送到 PHP

/en/section/123/1/slugtext 的请求应以 /front.php/en/section/123/1/slugtext 的形式发送到 PHP

/admin/api/Ping 的请求应以 /admin/admin_api.php/Ping 的形式发送到 PHP

/news/ 下的任何请求都应作为 /news/index.php 发送到 PHP

当然,这些重写只适用于不存在的文件/目录。

配置:

map $http_x_forwarded_proto $is_https{
    https on;
}

server {
        listen ip:80;
        server_name mydomain.tld;

        return  301 https://www.$server_name$request_uri;
}

server {
    listen ip:80;

    root /home/www/mydomain/shop/htdocs;

    server_name www.mydomain.tld;

    if ($http_x_forwarded_proto != "https") {
        return 301 https://$server_name$request_uri;
    }

    rewrite ^(.*)\.v[\d]+\.(css|js|png|jpg|jpeg|gif|eot|svg|ttf|woff|woff2)$ $1.$2;

    location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
        expires 30d;
        add_header Pragma public;
        add_header Cache-Control "public";
    }

    location = /favicon.ico {log_not_found off;access_log off;}
    location = /robots.txt {allow all;log_not_found off;access_log off;}
    location ~ /\. {deny all;}

    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /front.php$uri;
    }

    location ~ ^/admin/api(.*) {
            try_files $1 $1/ /admin/admin_api.php$1;
    }    

    location ^~ /news {
        alias /home/www/mydomain/wordpress/htdocs;
        index index.php;
        try_files $uri $uri/ /news/news/index.php?q=$uri&$args;
        location ~ \.php$ {
                try_files $uri =404;
                include fastcgi_params;
                fastcgi_pass unix:/run/php/php7.0-fpm-wordpress.sock;
                fastcgi_param SCRIPT_FILENAME $request_filename;
                fastcgi_param APPLICATION_ENV production;
                fastcgi_param PHP_VALUE default_charset=UTF-8;
                location ~* /(?:uploads|files)/.*\.php$ {deny all;}
            }
        location ~ /\. {deny all;}
    }

    location ~ [^/]\.php(/|$) {
        include fastcgi_params;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param HTTPS $is_https if_not_empty;
        fastcgi_param APPLICATION_ENV production;
        fastcgi_index index.php;
        fastcgi_param PHP_VALUE default_charset=ISO-8859-1;
        fastcgi_pass unix:/run/php/php7.0-fpm-shop.sock;
    }
}

这个配置是我能最接近工作的配置,但是当我请求/section.php时,它不再存在,前端控制器应该处理并生成一个301到新的URL,似乎Nginx忽略了/location块中的try_files(我猜是因为PHP更匹配),如果我将try_files直接移动到服务器块中,它的工作方式相同,如果我将它添加到PHP块中,它会覆盖/admin/api,并且所有API请求都会路由到front.php。

我在 Apache 中使用以下命令使其工作:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^admin/bbapi/(.*)$ /admin/admin_api.php/$1 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/news/
RewriteRule ^(.*)$ /front.php/$1 [L]

答案1

尝试添加以下内容:

location = /section.php {
    try_files /front.php$uri =404;
}

它将确保按section.php原样传递给front.php

相关内容