RewriteCond
これはApache でAND や OR を使用する方法ですか?
rewritecond A [or]
rewritecond B
rewritecond C [or]
rewritecond D
RewriteRule ... something
になりますif ( (A or B) and (C or D) ) rewrite_it
。
つまり、「OR」は「AND」よりも優先順位が高いということですか? 構文などで簡単に判別する方法はありますか(A or B) and (C or D)
?
ベストアンサー1
これは興味深い質問ですが、ドキュメントではあまり明確に説明されていないので、mod_rewriteのソースコード;大きなメリットを実証オープンソース。
上部のセクションでは、これらのフラグに名前を付けるために使用される定義:
#define CONDFLAG_NONE 1<<0
#define CONDFLAG_NOCASE 1<<1
#define CONDFLAG_NOTMATCH 1<<2
#define CONDFLAG_ORNEXT 1<<3
#define CONDFLAG_NOVARY 1<<4
CONDFLAG_ORNEXTを検索すると、それが使用されていることが確認されます[OR]フラグの存在に基づいて:
else if ( strcasecmp(key, "ornext") == 0
|| strcasecmp(key, "OR") == 0 ) {
cfg->flags |= CONDFLAG_ORNEXT;
}
次にこのフラグが出現するのは実際の実装ここで、RewriteRule が持つすべての RewriteConditions を処理するループが見つかります。基本的に実行される処理は次のとおりです (省略、わかりやすくするためにコメントを追加)。
# loop through all Conditions that precede this Rule
for (i = 0; i < rewriteconds->nelts; ++i) {
rewritecond_entry *c = &conds[i];
# execute the current Condition, see if it matches
rc = apply_rewrite_cond(c, ctx);
# does this Condition have an 'OR' flag?
if (c->flags & CONDFLAG_ORNEXT) {
if (!rc) {
/* One condition is false, but another can be still true. */
continue;
}
else {
/* skip the rest of the chained OR conditions */
while ( i < rewriteconds->nelts
&& c->flags & CONDFLAG_ORNEXT) {
c = &conds[++i];
}
}
}
else if (!rc) {
return 0;
}
}
これを解釈できるはずです。これは、OR の方が優先順位が高いことを意味し、あなたの例は確かに につながりますif ( (A OR B) AND (C OR D) )
。たとえば、次の条件があるとします。
RewriteCond A [or]
RewriteCond B [or]
RewriteCond C
RewriteCond D
と解釈されますif ( (A OR B OR C) and D )
。