Nginx重写规则为PHP,也允许在URI中.PHP


Nginx rewrite rule to PHP that also allows .php in the URI

有点不寻常的问题,希望有一个简单的答案!(I'm new to Nginx)

我有一个旧的PHP系统在Apache上运行,我想把它带到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的路由视为实际文件,并且只给我标准的"No input file specified "。错误对于任何不存在的(不执行重写)。如果没有。php扩展名,他们调用/handler.php没有问题。

总的来说,在这个几乎默认的设置下:

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

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

任何帮助都是感激的!

在你的位置块匹配.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提出了一个改进的替代方案。