В дополнение к ответу @whoisgregg (+1), который является хорошей адаптацией из Apache Wiki. Правила там не совсем хороши (например, управление доступом с помощью строки запроса на этой странице не устоит перед небольшим кодированием).
У нас есть рабочее решение для тестового примера, но некоторые расширенные тесты могут не пройти:
RewriteCond %{QUERY_STRING} ^(.*)lang=([a-z]{2})&?(.*)$
RewriteRule (.*) /%2/$1?%1%3 [R=307]
foo.php?foo=bar&novlang=fr&toto=titi => /fr/foo.php?foo=bar&novtoto=titi
Здесь часть lang=
обнаружена, но если какой-либо параметр заканчивается на lang , у вас возникнет проблема.
Итак, нам нужно исправить, я работал над этим вопросом на этой неделе, и вот лучшая версия, я думаю:
RewriteCond %{QUERY_STRING} (.*)(^|&|%26|%20)lang(=|%3D)([^&]+)(.*)$
RewriteRule (.*) /%4/$1?%1%5 [R=307]
foo.php?foo=bar&novlang=fr&toto=titi => not matched (normal, no lang=)
foo.php?foo=bar&lang=fr&toto=titi&b=a => fr/foo.php?foo=bar&toto=titi&a=b
Единственная проблема, ожидающая решения, заключается в том, что lang
может быть частично или полностью закодирован в URL и не будет обнаружен, но это редкий случай. Я также убрал контроль наличия только 2 символов на значении lang. Я думаю, что ([^&]+)
лучше, это означает, что все символы, пока я не совпаду с &
.