web-dev-qa-db-ja.com

複数の書き換え条件:一連のルールの前にそれらをチェーンする方法は?

Q1:これら2つの条件を連鎖させてそれらを作成する方法if BOTH A AND B, then proceed...
Q2:最初のルールだけでなく、以下のすべてのrewriteRulesに適用する方法は?

RewriteCond %{REQUEST_URI} ^IMAGE-.*$      // if filename starts with IMG- and,
RewriteCond %{REQUEST_FILENAME} !-f        // if file does exist, then proceed:
RewriteRule Rule1
RewriteRule Rule2
RewriteRule Rule3

# -- END IF -- STOP HERE -- #
24
Sam

ここでは、RewriteCondスタックを複数のRewriteRuleに適用するためのいくつかのトリックを、昇順 WTF's per minute でソートします。しかし、これは構成でありコードではないので、これらのルールは適用されませんよね? :-)

1.環境変数

RewriteCondが多数ある場合、それらの結果を環境変数に格納してから、すべてのルールに対してテストする方がコンパクトです。

# Your RewriteCond stack.
RewriteCond %{REQUEST_URI} !^IMAGE-.*$ [OR]
RewriteCond %{REQUEST_FILENAME} -f
# Store environment variable.
RewriteRule ^ - [E=TRUE:YEP]
# Assert environment variable in remaining RewriteRule's.
RewriteCond %{ENV:TRUE} =YEP
RewriteRule Rule1
RewriteCond %{ENV:TRUE} =YEP
RewriteRule Rule2
RewriteCond %{ENV:TRUE} =YEP
RewriteRule Rule3

2.フラグをスキップ

これは少し微妙です。 [S]または[skip]フラグを使用すると、RewriteRuleのブロック全体をスキップできます。

# Your RewriteCond stack.
RewriteCond %{REQUEST_URI} !^IMAGE-.*$ [OR]
RewriteCond %{REQUEST_FILENAME} -f
# If RewriteCond's match, skip the next RewriteRule.
RewriteRule ^ - [skip=1]
# Otherwise, this rule will match and the rest will be skipped.
RewriteRule ^ - [skip=3]
RewriteRule Rule1
RewriteRule Rule2
RewriteRule Rule3

これは、RewriteCondが条件であり、RewriteRuleがコードブロックであるifステートメントのようなものです。

重複は少なくなりますが、トレードオフはコードが不明確になるため、こののセットにルールを追加または削除するたびに[skip=N]を更新する必要があります[〜#〜 ] n [〜#〜]RewriteRule 's。

<楽しい>

さて、あなたがまだ読んでいるなら、ここに WTF's per minute が臨界点に達し、それを超える2つの解決策があります。彼らは娯楽のためだけのものであり、あなたはその理由を見るでしょう。

3. Nなしのフラグをスキップ

はい、[〜#〜] n [〜#〜]を含めずに[skip]フラグを使用する方法があります。 RewriteRuleは、RewriteCondスタックを適用します。つまり、各RewriteCondの前にRewriteRuleのペアを含めると、そうです、最後にもう1つ。

# Your RewriteCond stack.
RewriteCond %{REQUEST_URI} !^IMAGE-.*$ [OR]
RewriteCond %{REQUEST_FILENAME} -f
# If RewriteCond's match, skip the next RewriteRule.
RewriteRule ^ - [skip=1]  # succeeded
RewriteRule ^ - [skip=2]  # failed
RewriteRule Rule1
RewriteRule ^ - [skip=1]  # succeeded
RewriteRule ^ - [skip=2]  # failed
RewriteRule Rule2
RewriteRule ^ - [skip=1]  # succeeded
RewriteRule ^ - [skip=2]  # failed
RewriteRule Rule3
RewriteRule ^ -           # no-op to cover for last [skip=2] rule

ここでのトリックは、RewriteCondが成功した場合にのみすべての[skip=1]ルールが処理され、失敗した場合にのみすべての[skip=2]ルールが処理されることです。

4. URLマーカー

URLの一部を使用して状態を保持し、RewriteRuleでそれと照合します。

# Your RewriteCond stack.
RewriteCond %{REQUEST_URI} !^IMAGE-.*$ [OR]
RewriteCond %{REQUEST_FILENAME} -f
# If RewriteCond's match, prepend bogus marker "M#" to internal URL.
RewriteRule .* M#$0
# All your RewriteRule's test for this marker plus whatever else.
RewriteRule ^M#.*Rule1
RewriteRule ^M#.*Rule2
RewriteRule ^M#.*Rule3
# Finally, don't forget to strip off the bogus marker.
RewriteRule ^M#(.*) $1

マーカー付きの新しいURLは無効ですが、最後のRewriteRuleで元に戻しますよね?まあ、それが処理される場合にのみ、マーカーURLがこのラウンドのmod_rewrite処理をエスケープさせてから、元に戻してください。その後、404を取得します。

40
mxxk

Q1:デフォルトはANDです。

Q2:それらはすぐ下のRewriteRuleにのみ影響します。

22
Clodoaldo Neto

あなたはそれをそのように行うことはできません。 RewriteCondsを繰り返すか、参照を使用して書き換えルールを考え直して、すべてを1つのルールで実行する必要があります。最初のルートは、きれいではありませんが、最も簡単です。そう

RewriteCond A
RewriteCond B
RewriteRule 1

RewriteCond A #duplicate
RewriteCond B #duplicate
RewriteRule 2
16
XP84