Nginx重写规则到PHP,也允许URI中的.php

时间:2014-07-31 22:57:09

标签: nginx php

有点不寻常的问题,希望有一个简单的答案! (我是Nginx的新手)

我有一个在Apache上运行的旧PHP系统,我想把它带到Nginx,但我的问题是它的某些需要被重写回单个处理程序文件( /handler.php ),其中一些想要执行实际文件。棘手的部分似乎是几乎所有路由都以.php结尾,无论它们是否引用了实际的PHP文件。

例如, /foo.php 可能是执行自己代码的实际文件,但 /bar.php 可能不存在,因此想要调用 /handler.php 即可。还有一些 / bar (没有.php扩展名)的路由也需要调用 /handler.php

系统中有很多类型(远远超过我想手动编码的类型)。在Nginx中有解决方案吗?

服务器块目前包含以下内容:

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

include /etc/nginx/sites.d/*.conf;

和sites.d / php.conf目前看起来像:

location ~ \.php$
{
    fastcgi_pass    unix:/var/run/php5-fpm.sock;
    fastcgi_index   index.php;
    fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;

    include         /etc/nginx/fastcgi_params;
}

但是这会将带有.php扩展名的所有路由视为实际文件,只是给我标准的“没有指定输入文件。”错误任何不存在的错误(不执行重写)。没有问题,如果没有.php扩展名,他们会毫无问题地调用/handler.php。

总而言之,这几乎是默认设置:

/foo.php - works (actual file)
/bar.php - fails (no file)
/bar     - works (no file)

如果我只有“无文件”类型,我可以将php.conf更新为类似“location~ \ handler.php $”,但在这种情况下,它意味着所有实际的。 php文件只是触发下载(即/foo.php失败)。

任何帮助表示赞赏!提前谢谢。

1 个答案:

答案 0 :(得分:1)

在匹配 .php 的位置块中,您可以测试文件是否确实存在,并重定向到 handler.php ,如果它不存在:

location ~ \.php$ {
    if (!-f $request_filename) {
        rewrite ^.*\.php$ /handler.php last;
    }

    fastcgi_pass    unix:/var/run/php5-fpm.sock;
    fastcgi_index   index.php;
    fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;

    include         /etc/nginx/fastcgi_params;
}

更新了示例

使用 try_files 的替代位置规则(由OP建议):

location ~ \.php$ {
    try_files $uri /handler.php$is_args$args;

    fastcgi_pass    unix:/var/run/php5-fpm.sock;
    fastcgi_index   index.php;
    fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;

    include         /etc/nginx/fastcgi_params;
}

使用重写的第一个版本,您可以从正则表达式匹配进行替换。但 try_file 我认为是测试文件存在的推荐方法。感谢OP建议改进的替代方案。