mod_rewrite到nginx重写规则

时间:2012-07-31 01:54:12

标签: regex mod-rewrite nginx rewrite

我已将大部分Apache HTTPd mod_rewrite规则转换为nginx的HttpRewrite模块(在每个动态请求中通过FastCGI调用PHP-FPM)。由硬地点定义的简单规则可以正常工作:

location = /favicon.ico { rewrite ^(.*)$ /_core/frontend.php?type=ico&file=include__favicon last; }

我仍然遇到正则表达式的问题,这些正则表达式在mod_rewrite中被解析(注意我接受规则中的尾部斜杠,以及将查询字符串附加到每个请求):

mod_rewrite的

# File handler
RewriteRule ^([a-z0-9-_,+=]+)\.([a-z]+)$ _core/frontend.php?type=$2&file=$1 [QSA,L]

# Page handler
RewriteRule ^([a-z0-9-_,+=]+)$   _core/frontend.php?route=$1 [QSA,L]
RewriteRule ^([a-z0-9-_,+=]+)\/$ _core/frontend.php?route=$1 [QSA,L]

RewriteRule ^([a-z0-9-_,+=]+)\/([a-z0-9-_,+=]+)$   _core/frontend.php?route=$1/$2 [QSA,L]
RewriteRule ^([a-z0-9-_,+=]+)\/([a-z0-9-_,+=]+)\/$ _core/frontend.php?route=$1/$2 [QSA,L]

RewriteRule ^([a-z0-9-_,+=]+)\/([a-z0-9-_,+=]+)\/([a-z0-9-_,+=]+)$   _core/frontend.php?route=$1/$2/$3 [QSA,L]
RewriteRule ^([a-z0-9-_,+=]+)\/([a-z0-9-_,+=]+)\/([a-z0-9-_,+=]+)\/$ _core/frontend.php?route=$1/$2/$3 [QSA,L]

我已经为网站提供了以下服务器配置,但在解析请求后我遇到了无法匹配的规则(例如; GET /user/auth):

尝试nginx重写

location / {
    # File handler
    rewrite ^([a-z0-9-_,+=]+)\.([a-z]+)?(.*)$                                /_core/frontend.php?type=$2&file=$1&$3 break;

    # Page handler
    rewrite ^([a-z0-9-_,+=]+)(\/*)?(.*)$                                     /_core/frontend.php?route=$1&$2        break;
    rewrite ^([a-z0-9-_,+=]+)\/([a-z0-9-_,+=]+)(\/*)?(.*)$                   /_core/frontend.php?route=$1/$2&$3     break;
    rewrite ^([a-z0-9-_,+=]+)\/([a-z0-9-_,+=]+)\/([a-z0-9-_,+=]+)(\/*)?(.*)$ /_core/frontend.php?route=$1/$2/$3&$4  break;
}

您建议我处理我的文件处理程序(仅filename.ext)和我的页面处理程序(这是一个唯一的路由请求,最多由正斜杠定义的3个属性)?

由于我还没有得到回复,我也不确定这是否会覆盖我的PHP解析器,它是用location ~ \.php {}定义的,它包含在这些重写规则之前。

如果我可以解决解析问题而不需要为每个路由属性使用新规则,那么

奖励积分。

1 个答案:

答案 0 :(得分:2)

我最后写了以下规则:

文件处理程序

location ~ ^/([a-zA-Z0-9-_]*)\.([a-zA-Z0-9]*)$ { include /web/_config/php.conf; rewrite ^/([a-zA-Z0-9-_]*)\.([a-zA-Z0-9]*)$ /_core/frontend.php?type=$2&file=$1 last; }

文件处理程序获取名称和扩展名并将其写入type = {ext}& file = {name}。

页面处理程序

location ~ ^/([a-z0-9-_]*)$ { include /web/_config/php.conf; rewrite ^/([a-z0-9-_]*)$ /_core/frontend.php?route=$1 last; }
location ~ ^/([a-z0-9-_]*)/?([a-z0-9-_]*)$ { include /web/_config/php.conf; rewrite ^/([a-z0-9-_]*)/?([a-z0-9-_]*)$ /_core/frontend.php?route=$1/$2 last; }
location ~ ^/([a-z0-9-_]*)/?([a-z0-9-_]*)/?([a-z0-9-_]*)$ { include /web/_config/php.conf; rewrite ^/([a-z0-9-_]*)/?([a-z0-9-_]*)/?([a-z0-9-_]*)$ /_core/frontend.php?route=$1/$2/$3 last; }

页面处理程序(在本例中最多可处理3个“目录”)抓取每个分隔符(/)之间的字符串,进行正则表达式验证并将其作为查询字符串写入。

这与我的原始配置之间的主要区别在于每个条目都有自己的位置处理程序,并且在第一个匹配时处理它的last规则,因此性能应该稍好一些。

我还发现nginx默认添加查询字符串,因此不需要正则表达式,这是另一项性能提升。

请注意,/web/_config/php.conf只是一个FastCGI传递配置,nginx附带的配置(通常为/etc/nginx/fastcgi.conf)应该可以正常工作。请注意,如果您专门处理PHP,则无需在每个规则中对此进行定义,只需在其中添加include。

希望这有帮助。