webentwicklung-frage-antwort-db.com.de

Wie verwende ich "AND", "OR" für RewriteCond auf Apache?

Ist dies, wie man AND, OR für RewriteCond auf Apache verwendet?

rewritecond A [or]
rewritecond B
rewritecond C [or]
rewritecond D
RewriteRule ... something

wird zu if ( (A or B) and (C or D) ) rewrite_it.

Es scheint also, als ob "ODER" Vorrang vor "UND" hat. Gibt es eine Möglichkeit, wie in der Syntax (A or B) and (C or D) Leicht zu erkennen?

105

Dies ist eine interessante Frage, und da sie in der Dokumentation nicht sehr explizit erläutert wird, beantworte ich sie mit dem Quellcode von mod_rewrite ; zeigt einen großen Vorteil von Open Source.

Im oberen Bereich finden Sie schnell das Definitionen, mit denen diese Flags benannt werden :

#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

und die Suche nach CONDFLAG_ORNEXT bestätigt, dass es verwendet wird basierend auf der Existenz des [OR] -Flags :

else if (   strcasecmp(key, "ornext") == 0
         || strcasecmp(key, "OR") == 0    ) {
    cfg->flags |= CONDFLAG_ORNEXT;
}

Das nächste Vorkommen des Flags ist tatsächliche Implementierung . Hier finden Sie die Schleife, die alle RewriteConditions einer RewriteRule durchläuft, und was sie im Grunde tut, ist (entfernt, Kommentare zur Verdeutlichung hinzugefügt):

# 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;
    }
}

Sie sollten dies interpretieren können; es bedeutet, dass OR hat eine höhere Priorität, und Ihr Beispiel führt in der Tat zu if ( (A OR B) AND (C OR D) ). Wenn Sie zum Beispiel diese Bedingungen haben würden:

RewriteCond A [or]
RewriteCond B [or]
RewriteCond C
RewriteCond D

es würde als if ( (A OR B OR C) and D ) interpretiert.

106
Sjon