多个RewriteConditions:如何在一组规则之前链接它们?

Q1 :如何将这两个条件链接在一起, if BOTH A AND B, then proceed...
Q2 :如何让他们坚持下面的所有重写规则而不仅仅是第一条规则?

 RewriteCond %{REQUEST_URI} ^IMAGE-.*$ // if filename starts with IMG- and, RewriteCond %{REQUEST_FILENAME} !-f // if file does exist, then proceed: RewriteRule Rule1 RewriteRule Rule2 RewriteRule Rule3 # -- END IF -- STOP HERE -- # 

下面是使RewriteCond堆栈适用于多个RewriteRule的一些技巧, 按每分钟增加WTF的顺序排序。 但是这是配置而不是代码,所以这些规则不适用,对吧? 🙂

1.环境变量

当你有很多的RewriteCond的时候,把它们的结果存储在一个环境变量中,然后在每个规则中进行测试都是比较紧凑的。

 # Your RewriteCond stack. RewriteCond %{REQUEST_URI} !^IMAGE-.*$ [OR] RewriteCond %{REQUEST_FILENAME} -f # Store environment variable. RewriteRule ^ - [E=TRUE:YEP] # Assert environment variable in remaining RewriteRule's. RewriteCond %{ENV:TRUE} =YEP RewriteRule Rule1 RewriteCond %{ENV:TRUE} =YEP RewriteRule Rule2 RewriteCond %{ENV:TRUE} =YEP RewriteRule Rule3 

2.跳过标志

这个有点微妙 使用[S][skip]标志可以使整个RewriteRule块被跳过。

 # Your RewriteCond stack. RewriteCond %{REQUEST_URI} !^IMAGE-.*$ [OR] RewriteCond %{REQUEST_FILENAME} -f # If RewriteCond's match, skip the next RewriteRule. RewriteRule ^ - [skip=1] # Otherwise, this rule will match and the rest will be skipped. RewriteRule ^ - [skip=3] RewriteRule Rule1 RewriteRule Rule2 RewriteRule Rule3 

这就像一个if语句, RewriteCond是条件, RewriteRule是代码块。

你减少了重复,但折衷是代码不太清楚,你必须更新[skip=N]每次你添加或从这组N个 RewriteRule删除一个规则。

<乐趣>

好的,如果你还在阅读,在这里你会发现两个更多的解决方案,即每分钟跆拳道达到和超过临界点。 他们只是为了娱乐,你会明白为什么。

3.跳过没有N的标志

是的,有一种方法可以在不包括N的情况下使用[skip]标志,这是您要应用RewriteCond堆栈的RewriteRule的数量。 那是…如果你在每个RewriteRule之前加入一对RewriteCond ,那么最后还有一个。

 # Your RewriteCond stack. RewriteCond %{REQUEST_URI} !^IMAGE-.*$ [OR] RewriteCond %{REQUEST_FILENAME} -f # If RewriteCond's match, skip the next RewriteRule. RewriteRule ^ - [skip=1] # succeeded RewriteRule ^ - [skip=2] # failed RewriteRule Rule1 RewriteRule ^ - [skip=1] # succeeded RewriteRule ^ - [skip=2] # failed RewriteRule Rule2 RewriteRule ^ - [skip=1] # succeeded RewriteRule ^ - [skip=2] # failed RewriteRule Rule3 RewriteRule ^ - # no-op to cover for last [skip=2] rule 

这里的诀窍是,当且仅当RewriteCond成功时,每一个[skip=2]规则都得到处理,并且当且仅当它们失败时才处理每个[skip=2]规则。

4.网址标记

使用URL的一部分来保持状态,然后在你的RewriteRule匹配它。

 # Your RewriteCond stack. RewriteCond %{REQUEST_URI} !^IMAGE-.*$ [OR] RewriteCond %{REQUEST_FILENAME} -f # If RewriteCond's match, prepend bogus marker "M#" to internal URL. RewriteRule .* M#$0 # All your RewriteRule's test for this marker plus whatever else. RewriteRule ^M#.*Rule1 RewriteRule ^M#.*Rule2 RewriteRule ^M#.*Rule3 # Finally, don't forget to strip off the bogus marker. RewriteRule ^M#(.*) $1 

带有标记的新URL是无效的,但最后一个RewriteRule将它还原,对吗? 那么,只有当它被处理,所以不要让标记的URL转义这个mod_rewrite处理之前,它被恢复。 那么你会得到一个404。

Q1:默认是AND。

Q2:他们只会影响下面的RewriteRule。

你不能这样做。 您必须重复您的RewriteConds或重新考虑您的重写规则使用引用做这一切在一条规则。 第一条路线,虽然不美观,但会是最简单的。 所以

 RewriteCond A RewriteCond B RewriteRule 1 RewriteCond A #duplicate RewriteCond B #duplicate RewriteRule 2