多个URL重写规则(Prettify)

时间:2011-02-12 16:33:57

标签: .htaccess mod-rewrite

我有两种类型的网址:

http://mydomain.com/npguar/en/products.php
http://mydomain.com/npguar/en/1/product_specification.php

之前我使用此.htaccess进行网址重写:

RewriteEngine on
RewriteCond $1 !^(index\.php|assets|robots\.txt)
RewriteRule ^([a-z]{2})/(.*) $2?language=$1 [L]

然后我将其修改为此但它似乎无法正常工作

RewriteEngine on

RewriteCond $1 ^(product_specification\.php)
RewriteRule ^([a-z]{2})/([0-9]{1,2})(.*) $3?language=$1&id=$2 [L]

RewriteCond $1 !^(index\.php|assets|robots\.txt|product_specification\.php)
RewriteRule ^([a-z]{2})/(.*) $2?language=$1 [L]

1 个答案:

答案 0 :(得分:2)

以下是原始规则的工作原理。从URL开始:

http://mydomain.com/npguar/en/index.php?maybe=a-query

仅采用文件系统路径:

npguar/en/index.php

删除用于转到.htaccess的前缀:

en/index.php

将此与正则表达式^([a-z]{2})/(.*)匹配。它匹配,因此处理继续。正则表达式中有子模式,它匹配部分URL,如下所示:

(en)/(index.php)

此匹配定义了后向引用$1 = en$2 = index.php

现在检查相应的RewriteCond。第一个参数是$1,它扩展为字符串en。第二个参数是!,和一个与该字符串不匹配的正则表达式,因此条件为真。

由于条件为真,请返回RewriteRule并构造替换字符串$2?language=$1

index.php?language=en

这是一个内部重定向,所以将原始网址的位重新组合在一起。由于此处存在查询且未指定[QSA]标记,因此原始查询(maybe=a-query)将被替换。

http://mydomain.com/npguar/index.php?language=en

此URL将从一开始就交回Apache进行处理。再次检查重写规则([L]标志不会阻止此操作),但它们不匹配,并且页面已提供。


此规则的问题是$1中的RewriteCond。它应该是$2。然后,RewriteCond在上面的示例中将为false,但在en/products.php中为真。

这样可以正常工作,因为RewriteCond比你想要的要宽松。

新规则不起作用,因为正则表达式会破坏这样的网址(请注意第二个/所在的位置):

(en)/(1)(/product_specification.php)

所以$1 = en$2 = 1$3 = /product_specification.php。然后它将$1^product_specification.php进行比较,它不匹配,条件为false。

相反,新规则应为:

RewriteCond $3 ^product_specification\.php$
            ^^                            ^
RewriteRule ^([a-z]{2})/([0-9]{1,2})/(.*) $3?language=$1&id=$2 [L]
                                    ^

(我还在最后添加了$,以便.../product_specification.phpfoo不匹配。)

同样的规则可以简单地说:

RewriteRule ^([a-z]{2})/([0-9]{1,2})/(product_specification\.php)$ $3?language=$1&id=$2 [L]