如何在 htaccess 中使用 RewriteCond 编写(A 和 B)或(C 和 D)?

How to write (A and B) or (C and D) with RewriteCond in htaccess?

如何创建以下逻辑: (A 和 B)或(C 和 D) 使用 RewriteCond?

这里的文档不是很清楚,所以我希望一些专家能给出一些启发。

我查看了以下内容post: how to use "AND", "OR" for RewriteCond on Apache? 这个对于给定的例子来说有点清楚,但我还是有点卡住了。

举个例子。如果我需要(A 和 B)或(C 和 D),这是否正确?还是A和(B或C)和D?

RewriteCond A
RewriteCond B [OR]
RewriteCond C
RewriteCond D

下面是(A and B and C)还是D,还是A and B and (C or D)?

RewriteCond A
RewriteCond B
RewriteCond C [OR]
RewriteCond D

是否只有将它们拆分成多个 RewriteRules 才能解决?

注意:所有代码示例都是半伪代码,除非另有说明。


这是一个有趣的问题,但是,您如何实际实现这样的东西实际上取决于您想要实现的目标。有几个 methods/techniques 可以完成这项工作。

您不能像示例中那样从字面上实现此逻辑,即。有 4 个条件:A、B、C 和 D。并使用 OR 和(隐含的)AND 标志。这是因为条件是按从上到下的顺序处理的,OR 优先于隐含的 AND 并且 group 没有语法条件一起(除了拆分成单独的规则)。

RewriteCond A
RewriteCond B [OR]
RewriteCond C
RewriteCond D

这等同于A and (B or C) and D。如果不满足条件,处理会提前停止。因此,在此示例中,如果 A 失败,则不会进行进一步处理。

RewriteCond A
RewriteCond B
RewriteCond C [OR]
RewriteCond D

这等同于A and B and (C or D)

How can I create the following logic: (A and B) or (C and D) with RewriteCond?

在一般意义上,有多种方法可以实现此逻辑,具体取决于预期的操作。在 Apache 2.4 上,您可以在 RewriteCond 指令中嵌入 Apache 表达式,这样您就可以更准确地执行以下操作:

RewriteCond expr "A && B" [OR]
RewriteCond expr "C && D"

(虽然这甚至可以组合成一个条件。)

或者,直接使用 Apache <If> 表达式。例如:

<If "(A && B) || (C && D)">
    RewriteRule ^ something
</If>

在早期版本的 Apache 上,您可以使用环境变量(存储中间表达式的结果)and/or skip 规则取决于早期条件的结果.

例如:

# If "A and B" then env var is set and the next rule is skipped
RewriteCond A
RewriteCond B
RewriteRule ^ - [E:A_AND_B:1,S=1] 

# If "C and D" then env var is set
RewriteCond C
RewriteCond D
RewriteRule ^ - [E:C_AND_D:1]

RewriteCond A_AND_B [OR]
RewriteCond C_AND_D
RewriteRule <do-this>

尽管您不需要上面的两个环境变量 - 一个就可以了:

# If "A and B" then env var is set and the next rule is skipped
RewriteCond A
RewriteCond B
RewriteRule ^ - [E:SUCCESS:1,S=1] 

# If "C and D" then env var is set
RewriteCond C
RewriteCond D
RewriteRule ^ - [E:SUCCESS:1]

# If neither "A and B" or "C and D" is set then SUCCESS is also not set
RewriteCond SUCCESS
RewriteRule <do-this>

或者,skipchain 一起规则(不需要环境变量):

# If "A and B" then skip the next rule that checks "C and D"
RewriteCond A
RewriteCond B
RewriteRule ^ - [S=1]

# If "C and D" then chain to the next rule
RewriteCond C
RewriteCond D
RewriteRule ^ - [C]

# (A and B) or (C and D) - Otherwise this rule is skipped
RewriteRule <do-this>

但是,根据您正在做的事情,您还可以使用对较早条件的反向引用将正则表达式和“link”条件一起发挥创意。例如,参见 to the following question: