Apache पर RewriteCond के लिए “AND”, “OR” का उपयोग कैसे करें?


115

यह कैसे और, या RewriteCondअपाचे पर उपयोग करने के लिए है ?

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

बन जाता है if ( (A or B) and (C or D) ) rewrite_it

तो ऐसा लगता है कि "या" "और" की तुलना में अधिक पूर्वता है? क्या (A or B) and (C or D)सिंटैक्स में आसानी से बताने का कोई तरीका है ?


1
हाँ सही। [या] (अनुमानित) "और" की तुलना में अधिक पूर्वता है। संयुक्त स्थिति वास्तव में है ((ए या बी) और (सी या डी))।
चल रहा

2
आप ckollars.org/apache-rewrite-htaccess.html#precedence में मददगार हो सकते हैं ।
चक कोलारस

जवाबों:


118

यह एक दिलचस्प सवाल है और चूंकि इसे प्रलेखन में बहुत स्पष्ट रूप से नहीं समझाया गया है, इसलिए मैं 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 की खोज इस बात की पुष्टि करती है कि इसका उपयोग [या] ध्वज के अस्तित्व के आधार पर किया जाता है :

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

झंडे की अगली घटना वास्तविक कार्यान्वयन है जहां आपको वह लूप मिलेगा जो सभी रिवेट्रिटकॉन्डिशन के माध्यम से जाता है, जो कि एक रिवरराइट है, और यह मूल रूप से क्या करता है (छीन लिया गया, टिप्पणी स्पष्टता के लिए जोड़ा गया):

# 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 )


1
यह मुझे लगता है कि उदाहरण के स्रोत कोड का निष्पादन .htaccess दिए गए ((या OR B) और C) या D) [अर्थात न तो ओपी को उम्मीद है और न ही आपने शुरू में जो गणना की है]। क्या आप मेरी व्याख्या में त्रुटि खोजने में मेरी मदद कर सकते हैं? [इसके अलावा और अधिक जानने के लिए, रिवर्स के बारे में क्या: यदि कोई लागू करना चाहता है ((ए या बी) और (सी या डी)), तो वास्तव में .htaccess फ़ाइल में एक कोड क्या होना चाहिए?]
चक कोलारस

3
+1 'ओपन-सोर्स के एक बड़े लाभ का प्रदर्शन' के लिए :) - @ChuckKollars तर्क का उत्पादन नहीं करेगा (((ए या बी) और सी) या डी) लेकिन (ए या बी) और (सी या डी)। प्रत्येक पास पर हालांकि लूप यह जाँच करता है CONDFLAG_ORNEXT जो केवल ए और सी को देखते समय सेट किया जाएगा। जब इसे सेट किया जाता है तो यह या तो अगली स्थिति को छोड़ देता है यदि वर्तमान स्थिति बीत गई या यह ध्यान नहीं दे रहा है कि वर्तमान स्थिति विफल हो गई है क्योंकि भविष्य की स्थिति पास और ओआर समूह के अंतिम में ध्वज सेट नहीं होगा, यदि सभी विफल हो जाते हैं तो पूरी चीज विफल हो जाती है।
अस्थायी

1
कैसे ((ए और बी) या (सी और डी) के आसपास मेरे सिर नहीं मिल सकता है - मैं (ए और (बी या सी) और डी) के साथ समाप्त हो गया है
पीट

@WillshawMedia आप इसे दो अलग-अलग नियमों में विभाजित करके ((A और B) OR (C और D) कर सकते हैं: RewriteCond A RewriteCond B RewriteRule AB रिवरिटकॉन्ड C RewriteCond डी रिवरटाइंड सीडी
इसहाक

3

कई संघर्षों के बाद और एक, सामान्य लचीला और अधिक पठनीय समाधान हासिल करने के लिए, मेरे मामले में मैं बचत समाप्त हो गया या में s परिणाम ENV चर और कर और रों उन चर के।

# RESULT_ONE = A OR B
RewriteRule ^ - [E=RESULT_ONE:False]
RewriteCond ...A... [OR]
RewriteCond ...B...
RewriteRule ^ - [E=RESULT_ONE:True]

# RESULT_TWO = C OR D
RewriteRule ^ - [E=RESULT_TWO:False]
RewriteCond ...C... [OR]
RewriteCond ...D...
RewriteRule ^ - [E=RESULT_TWO:True]

# if ( RESULT_ONE AND RESULT_TWO ) then ( RewriteRule ...something... )
RewriteCond %{ENV:RESULT_ONE} =True
RewriteCond %{ENV:RESULT_TWO} =True
RewriteRule ...something...

आवश्यकताएँ :

  • Apache mod_env सक्षम किया गया
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.