2009-05-28 8 views
87

Ist das, wie AND, OR für RewriteCond auf Apache zu verwenden?wie "AND", "OR" für RewriteCond auf Apache zu verwenden?

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

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

So scheint es, dass "ODER" höhere Priorität als "UND" hat? Gibt es eine Möglichkeit, einfach zu sagen, wie in der (A or B) and (C or D) Syntax?

+0

Ja, richtig. [OR] hat eine höhere Priorität als das (implizite) "AND". Die kombinierte Bedingung ist tatsächlich ((A oder B) und (C oder D)). – Doin

+1

Sie finden die Details in http://www.ckollars.org/apache-rewrite-htaccess.html#precedence hilfreich. –

Antwort

86

Dies ist eine interessante Frage und da es nicht sehr explizit in der Dokumentation erklärt wird, beantworte ich dies durch die sourcecode of mod_rewrite; demonstriert einen großen Vorteil von open-source.

Im oberen Bereich finden Sie schnell die defines used to name these flags beschmutzen 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 based on the existence of the [OR] flag verwendet wird:

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

Das nächste Vorkommen der Flagge ist die actual implementation Hier finden Sie die Schleife, die alle RewriteConditions durchläuft, die eine RewriteRule hat, und was sie im Grunde tut (stripped, Kommentare wurden zur besseren Übersicht 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 in der Lage sein, dies zu interpretieren; Es bedeutet, dass OR eine höhere Priorität hat, und Ihr Beispiel führt tatsächlich zu if ((A OR B) AND (C OR D)). Wenn Sie zum Beispiel folgende Umstände:

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

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

+0

Es scheint mir, dass die Ausführung des Quellcodes in dem gegebenen Beispiel .htaccess ((A ODER B) und C) oder D) [d.h. weder was das OP hofft noch was du ursprünglich berechnet hast]. Kannst du mir helfen, meinen Interpretationsfehler zu finden? [Auch um genauer zu sein, was ist mit dem umgekehrten: wenn man ((A ODER B) UND (C ODER D)) implementieren will, was genau soll man in der .htaccess-Datei codieren?] –

+3

+1 für 'demonstrieren a großer Vorteil von Open-Source ':) - @ChuckKollars die Logik würde nicht produzieren (((A oder B) und C) oder D), aber (A oder B) und (C oder D). Bei jedem Durchgang überprüft die Schleife CONDFLAG_ORNEXT, was nur bei Betrachtung von A und C gesetzt werden würde. Wenn es gesetzt ist, überspringt es entweder die nächste Bedingung, wenn die aktuelle Bedingung bestanden hat, oder es macht weiter nichts aus, dass die aktuelle Bedingung fehlgeschlagen ist, weil zukünftige Bedingungen möglich sind Pass und der letzte der OR-Gruppe wird nicht das Flag gesetzt, wenn alle fehlschlagen das ganze Ding scheitert. – Logikos

+0

Sehr gute Antwort auf eine gute Frage. Vielen Dank. – Jpsy

Verwandte Themen