php - 动态 URL 段的 Nginx 位置 block

标签 php nginx

我的 PHP 应用程序自动检测到请求通过 url 中的关键字 manage 路由到管理区域,即:

http://example.com/manage

这个目录实际上并不存在。

请求应该路由到 index.php 文件,该文件在初始请求上执行以管理/但任何链接都会产生“未指定输入文件”。 nginx 错误。

我需要一个可以在不存在的 url 段上工作的位置 block 。

我试着像这样将它重写到主索引文件中:

location /manage {
    try_files $uri $uri/ @back;
}

location @back {
    rewrite ^/manage/(.*)$ /index.php?_route_=$1 last;
}

这对 Apache 工作正常,但在 Nginx 中这会产生 500 错误。

如有任何建议,我们将不胜感激。

更新:

评论中要求的完整配置:

upstream myapp {
    server unix:/srv/users/serverpilot/run/myapp.php-fpm.sock;
}

server {
    listen 80;
    server_name my.domain.com;

    root /srv/users/serverpilot/apps/myapp/public;
    index index.php index.html index.htm;

    access_log /srv/users/serverpilot/log/myapp/myapp_nginx.access.log;
    error_log  /srv/users/serverpilot/log/myapp/myapp_nginx.error.log;

    location /asset {
        rewrite ^/asset/(.*)$ /public/asset/$1 break;
    }

    location /image {
        rewrite ^/image/(.*)$ /public/image/$1 break;
    }

    location / {
        try_files $uri $uri/ @front;
    }

    location @front {
        rewrite ^/(.+)$ /index.php?_route_=$1 last;
    }

    location ~ \.php$ {
        include fastcgi.conf;
        fastcgi_pass myapp;
    }
}

更新:

请求错误日志。

15/05/14 10:42:04 [error] 32704#0: 
*5 FastCGI sent in stderr: 
"Unable to open primary script: /srv/users/username/apps/myapp/public/manage/index.php (No such file or directory)" 
while reading response header from upstream, client: 129.349.569.789, 
server: myapp.example.com, 
request: "GET /manage/index.php?route=common/forgotten HTTP/1.1", 
upstream: "fastcgi://127.0.0.1:9002", 
host: "myapp.example.com", 
referrer: "http://myapp.example.com/manage"

更新:

请求.htaccess文件:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^(.*)/$ /$1 [L,R=301]
    RewriteRule ^asset/(.*)$ public/asset/$1 [L,QSA]
    RewriteRule ^image/(.*)$ public/image/$1 [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|txt|html|woff|ttf|eot|svg|css|js)
    RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]
</IfModule>

最佳答案

根据您发布的错误日志和配置,/manage/index.php?route=common/forgotten 的请求将同时匹配 / php 位置 block 。

鉴于 Nginx Location Matching Order设置后,PHP 位置 block 将始终优先,因此请求将传递给 FastCGI 进行处理,并且由于 site.com/manage/index.php 不存在,您会收到错误消息。也就是说,/ 中的 try_files@front 中的重写根本不会出现。

你需要做的是添加一个位置匹配顺序比PHP位置 block 更高的位置 block 来处理这样的请求。

upstream myapp {
    server unix:/srv/users/serverpilot/run/myapp.php-fpm.sock;
}

server {
    listen 80;
    server_name example.com;

    root /srv/users/serverpilot/apps/myapp/public;
    index index.php index.html index.htm;

    access_log /srv/users/serverpilot/log/myapp/myapp_nginx.access.log;
    error_log  /srv/users/serverpilot/log/myapp/myapp_nginx.error.log;

    location /asset {
        rewrite ^/asset/(.*)$ /public/asset/$1 break;
    }

    location /image {
        rewrite ^/image/(.*)$ /public/image/$1 break;
    }

    location / {
        try_files $uri $uri/ @front;
    }

    location ~ ^/manage {
        rewrite ^([^?]*)$ /index.php?_route_=$1;
    }

    location ~ \.php$ {
        include fastcgi.conf;
        fastcgi_pass myapp;
    }

    location @front {
        rewrite ^([^?]*)$ /index.php?_route_=$1;
    }
}

通过这种安排,请求将匹配 //Managephp 位置 block 。 /Managephp 是正则表达式类型的 block ,将优先并且在两者中,/Manage,因为它先出现,所以将优先并且相应地重定向。

对于重定向,请求将匹配 /php 位置 block 。 php 将优先,因为 site.com/index.php 确实存在,因此进行相应处理。

附言。我注意到您的配置中有 _route_,日志中有 route。把它当作测试用吧。

**** 替代配置 ****

upstream myapp {
    server unix:/srv/users/serverpilot/run/myapp.php-fpm.sock;
}

server {
    listen 80;
    server_name example.com;

    root /srv/users/serverpilot/apps/myapp/public;
    index index.php index.html index.htm;

    access_log /srv/users/serverpilot/log/myapp/myapp_nginx.access.log;
    error_log  /srv/users/serverpilot/log/myapp/myapp_nginx.error.log;

    location ~ \.php$ {
        include fastcgi.conf;
        fastcgi_pass myapp;
    }

    location ~ ^/asset/(.*)$ {
        rewrite ^ public/asset/$1;
    }

    location ~ ^/image/(.*)$ {
        rewrite ^ public/image/$1;
    }

    location / {
        rewrite ^/(.+)/$ /$1 permanent;
        try_files $uri $uri/ @front;
    }

    location @front {
        rewrite ^/([^?]*)$ /index.php?_route_=$1;
    }   
}

关于php - 动态 URL 段的 Nginx 位置 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29961468/

相关文章:

php - 如何在 Amazon EC2 上创建子域?

php - 使用redis在laravel中排队

ruby-on-rails - Rails + 乘客 bundler 错误

nginx - 为什么当我尝试挂载卷时 Docker 无法打开 nginx.conf?

mysql - Nginx Docker 卷为空

PHP 根据对应的计数数组创建多维数组

PHP。为什么日期对象 diff on month 在 12 个月后重置为 0?

php - 用于在 '' 附近使用正确语法的 MySQL 服务器版本

nginx - Jupyterhub 和 nginx 反向代理配置

wordpress - 为什么不 chown -R root :www-data work on my Wordpress installation?