Небольшая шпаргалка для самого себя, а может быть, и еще кому-то пригодится.
Исходные данные: В индексе Гугла и Яндекса есть как ссылки вида index.php?category=privet, так и ссылки вида /category/privet. Требуется “склеить” их таким образом, чтобы поисковики не предлагали переход на index.php?category=privet, только лишь на /category/privet.
Любой “несуществующий” URL обрабатывается CMS, находящейся по адресу /index.php – правила нужны лишь для поисковиков. Благодаря этому не будет зацикливания (иногда CMS преобразовывают URL вида /category/privet, наоборот, в /index.php?category=privet – в этом случае, будет зацикливание. Избежать его можно переменными окружения, или же использовать другой веб-сервер). Ну да зацикливание в правилах mod_rewrite – совсем другая история, достойная отдельной статьи или даже целой книги.
Могу лишь дать маленький, но очень ценный (на мой очень-очень скромный взгляд) совет: использование фреймворков или CMS, в которых роутинг целиком осуществляется в index.php (без учета GET параметров), – это очень здорово!
Пример: Kohana, Symfony, OnPHP. Из CMS – пожалуй, TextPattern.
Итак, меньше болтовни и больше дела.
Первый этап: анализируем, есть ли в QUERY_STRING (в нашем примере - он равен category=privet), параметр category. Если он есть, перенаправляем через 301 редирект на /category/privet.
RewriteCond %{QUERY_STRING} category=([^&]*) RewriteRule ^index.php /category/%1 [L,R=301]
Результат неоптимальный. Переход осуществляется на /category/privet?category=privet. Уберем лишний параметр, присвоив QUERY_STRING пустое значение:
RewriteCond %{QUERY_STRING} category=([^&]*) RewriteRule ^index.php /category/%1? [L,R=301]
Если необходима переадресация только для точных вхождений, можно ужесточить наше правило:
RewriteCond %{QUERY_STRING} ^category=([^&]*)$ RewriteRule ^index.php /category/%1? [L,R=301]
В этом случае, запрос вроде index.php?category=privet& уже не будет преобразован в правильный URL. Нужно это или нет - решать уже вам.