Справочные группы захвата нескольких RewriteCond в RewriteRule
Когда у меня есть несколько RewriteCond, соединенных вместе, только ссылки на группы RewriteCond могут ссылаться на %0
- %9
.
В следующей задаче параметры в строке запроса 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]
Это должно сработать, но для каждого дополнительного параметра он становится более беспорядочным. Другим решением может быть синтаксический анализ одного параметра и перенаправление клиента после каждого параметра (что приводит к длительной цепочке перенаправления, чего я бы хотел избежать).
Существует ли более чистый способ доступа к группам захвата всех RewriteCond в RewriteRule (например, можно ли назвать их или назначить их переменной, чтобы я мог ссылаться на них где-то еще?)
Ответы
Ответ 1
Вы можете попытаться создать целевой 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¶m2=b¶m6=3¶m3=4¶m5=5¶m4=6
Я перенаправляюсь на:
/bar/a/b/4/6/5/3
Добавление любых дополнительных обязательных параметров строки запроса не сделает его более грязным, чем оно уже есть.
Ответ 2
После нескольких экспериментов можно было бы проанализировать все параметры как переменные среды и использовать их так. Я сомневаюсь, что это очень эффективно, хотя и я думаю, что любой случай использования, который потребует такой конструкции, будет лучше использовать маршрутизатор 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]