我有两种类型的网址:
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]
答案 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]