2013-07-22 14 views
10

複数のRewriteCondを連結すると、最後のRewriteCondのキャプチャグループのみが%0 - %9で参照できます。RewriteRule内の複数のRewriteCondの参照キャプチャグループ

次の問題では、URLのクエリ文字列のパラメータは任意の順序で指定できます。派手なURLにそれらを解析するために、私は個別にクエリ文字列内の各パラメータと一致する必要があります:

RewriteCond %{QUERY_STRING} param1=([^&]+) 
RewriteCond %{QUERY_STRING} param2=([^&]+) 
RewriteCond %{QUERY_STRING} param3=([^&]+) 
RewriteRule ^foo$ bar/%1/%2/%3/ [R] 

私は指摘のように...これは動作しません。この問題を解決するために、私は次のRewriteCondで、前のRewriteCondのキャプチャグループを参照する可能性があり、実際のRewriteRuleに各パラメータを「伝播」:

RewriteCond %{QUERY_STRING} param1=([^&]+) 
RewriteCond %1&%{QUERY_STRING} ^([^&]*)&.*param2=([^&]+) 
RewriteCond %1&%2&%{QUERY_STRING} ^([^&]*)&([^&]*)&.*param3=([^&]+) 
RewriteRule ^foo$ bar/%1/%2/%3/ [R] 

これは動作するはずですが、それぞれの追加のパラメータのためには、メシエのを取得します。他の解決方法は、1つのパラメータを解析し、各パラメータの後にクライアントをリダイレクトすることができます(リダイレクトのチェーンが長くなりますので避けたい)。

はするRewriteRule内のすべてのRewriteCond年代のキャプチャグループにアクセスするためのクリーンな方法(例えば、私はどこか別の場所にそれらを参照することができますので、それらに名前を付けたり、変数に割り当てることが可能ですか?)あり

+2

+1を。私はこの問題にも直面しており、答えを知りたいと思っています – anubhava

+0

mod_rewriteのドキュメントでは、RewriteCondの逆参照は、現在の条件セットで**最後に一致したRewriteCond **を保持するだけなので、このルートでのみ答えます。その複雑さを考えると、GETやPOSTを解析する 'foo'でスクリプトを設定し、適切な' bar'にリダイレクトすることを考えましたか? – miah

答えて

10

あなたは試みることができます書き換え条件内のターゲットURLの構築:

RewriteCond ##%{QUERY_STRING}  (.*)##(|.*&)param1=([^&]+) 
RewriteCond %1/%3##%{QUERY_STRING} (.*)##(|.*&)param2=([^&]+) 
RewriteCond %1/%3##%{QUERY_STRING} (.*)##(|.*&)param3=([^&]+) 
RewriteCond %1/%3##%{QUERY_STRING} (.*)##(|.*&)param4=([^&]+) 
RewriteCond %1/%3##%{QUERY_STRING} (.*)##(|.*&)param5=([^&]+) 
RewriteCond %1/%3##%{QUERY_STRING} (.*)##(|.*&)param6=([^&]+) 

RewriteRule ^foo$ /bar%1/%3? [L,R] 

私が要求にしようとすると:

/foo?param1=a&param2=b&param6=3&param3=4&param5=5&param4=6

それがすでにあるよりも、これ以上の厄介に見えることはありません任意の追加の 必要クエリ文字列パラメータを追加

/bar/a/b/4/6/5/3

:0

私はにリダイレクトされます。

+0

'##'は何のために使われていますか? –

+0

@RahilWazirそれはちょうどデリミタとして使用されていますが、私たちはuriの中に '# 'はありませんので、安全です。 –

+0

これは必要でしたか?区切り記号がないと意味がありません(まだ分かりません)。 –

1

もう少し実験した後、すべてのパラメータを環境変数として解析し、そのように使用することができます。私はそれが非常に効率的だとは思わないし、私はそのような構築を必要とするユースケースは、PHPページのルータを使用するのが良いだろうと思う。派手なURLのために、Jon Linのソリューションがうまくいくでしょう。しかし、それは私が気にしていたことをまねしています。

私は、しかし、デモのために、ここでのコードを入れます:偉大な質問のための

#Parse all query key-value pairs to an environment variable with the q- prefix 
RewriteCond %{QUERY_STRING} ^([^=]*)=([^&]*)(&(.*)|$)$ 
RewriteRule ^(.*)$ $1?%4 [E=q-%1:%2,N] 

#If 'param1' existed in the query string... 
RewriteCond %{ENV:q-param1} !^$ 
RewriteRule ^foo$ bar/%{ENV:q-param1} [END] 

たり...

#Keep the original query string 
RewriteCond %{ENV:qstring} ^$ 
RewriteCond %{QUERY_STRING} ^(.*)$ 
RewriteRule .* - [E=qstring:#%1] 

#parse the query parameters to environment variables 
RewriteCond %{ENV:qstring} ^#([^=]*)=([^&]*)(&(.*)|$)$ 
RewriteRule ^(.*)$ - [E=q-%1:%2,E=qstring:#%4,N] 

#See that the original query string is still intact 
RewriteCond %{ENV:q-param1} !^$ 
RewriteRule ^foo$ bar/%{ENV:q-param1} [QSA] 
関連する問題