123

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ます。

「AND」よりも「OR」の方が優先度が高いようですね。(A or B) and (C or D)構文のように、簡単に伝える方法はあり ますか?

4

2 に答える 2

132

これは興味深い質問です。ドキュメントではあまり明確に説明されていないため、 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 )ます。

于 2015-07-22T19:11:46.607 に答える