Редирект с сортировкой и удалением лишних параметров

lag

Мой дом здесь!
Регистрация
13 Окт 2014
Сообщения
290
Реакции
366
Атрибут rel="canonical" конечно рулит, но любопытно расставить интересующие параметры строго в одном порядке именно средствами mod_rewrite.
Допустим, есть три параметра param1,param2,param3 и в адресе они должны быть объявлены именно в таком порядке и при любых перестановках нужно делать редирект на адрес с правильным порядком, попутно удаляя любые лишние параметры.
Реализовать думаю так: извлекать параметры по одному, попутно собирая их в строку в нужном порядке, после сравнить с исходной строкой параметров и только в случае несовпадения делать редирект, используя собранную в нужном порядке строку.

Например:
/?param3=lol&bla=bla&param1=foo&param2=bar => /?param1=foo&param2=bar&param3=lol

Код:
RewriteCond &%{QUERY_STRING}  &(param1=[^&]+)
RewriteCond %1\ &%{QUERY_STRING}  ^(\S+).+(&param2=[^&]+)
RewriteCond %1%2\ &%{QUERY_STRING} ^(\S+).+(&param3=[^&]+)
RewriteCond %1%2\ %{QUERY_STRING}  ^(\S+)\ (?!\1$)
RewriteRule .* /$0?%1 [R=301,L]

Эти правила делают редирект только для адресов, где есть все три параметра.
Если какие-то из параметров необязательные решить можно так:

Код:
RewriteCond &%{QUERY_STRING} (?:(&param1=[^&]+)|(&param2=[^&]+)|(&param3=[^&]+)|&[^&]+)+
RewriteCond &%1%2%3\ %{QUERY_STRING} ^&++(\S*)\ (?!\1$)
RewriteRule .* /$0?%1 [R=301,L]

Или так
Код:
RewriteCond &%{QUERY_STRING} (?:(&param1=[^&]+)|(&param2=[^&]+)|(&param3=[^&]+)|&[^&]+)+
RewriteCond &%1%2%3\ %{THE_REQUEST} ^&++(\S*+)[^?]+\?(?!\1[#\ ])
RewriteRule .* /$0?%1 [R=301,L]
 
Проблема насущная. Я тоже не люблю каноникалов и стараюсь всё зарезать, но от твоих правил просто диву даюсь.
Ты где учился такие конструкции ваять? Есть какой-нить небольшой курс по ваянию такого?
 
Проблема насущная. Я тоже не люблю каноникалов и стараюсь всё зарезать, но от твоих правил просто диву даюсь.
Ты где учился такие конструкции ваять? Есть какой-нить небольшой курс по ваянию такого?
Я тоже коду lag'а удивляюсь. Спрашиваешь - все отвечают или громоздким кодом или вообще не тем. А у него любая ситуация разрешима изящно, быстро и коротко, без всякой ерундятины
 
Очень хорошая книга "Регулярные выражения" автор Джеффри Фридл.

Еще подумал тут возможен конфликт с другими правилами которые перезаписывают параметры вроде RewriteRule ^babla/$ index.php?page=blabla
Правила должны делать проверку только один раз и до того как другие правила внесли изменения в строку параметров.
Нужно установить переменную окружения это будет сигналом что проверка прошла и повторно её делать не требуется.
Код:
RewriteCond %{ENV:REDIRECT_FIRST} ^$

RewriteCond &%{QUERY_STRING} (?:(&param1=[^&]+)|(&param2=[^&]+)|(&param3=[^&]+)|&[^&]+)+
RewriteCond &%1%2%3\ %{QUERY_STRING} ^&++(\S*)\ (?!\1$)
RewriteRule .* /$0?%1 [R=301,L]

RewriteRule ^ - [E=FIRST:1]
 
Последнее редактирование:
  • Нравится
Реакции: UJy
Очень хорошая книга "Регулярные выражения" автор Джеффри Фридл.
В книге есть раздел сугубо по htaccess? Насколько я понимаю, чисто знание регулярок не слишком то поможет в составлении "таких" правил. Полюбому есть свод правил по работе в htaccess, а регулярки лишь метода отлова урлов.

Ну либо я сильно ошибаюсь в своих пониманиях htaccess - поправьте меня, если это так.
 
В книге среди прочего есть про библиотеку PCRE, которая используется Apache и PHP.
А про .htaccess точно подмечено в статье Для просмотра ссылки Войди или Зарегистрируйся
Проблема заключается в том, что для хорошего понимания работы mod_rewrite требуется изучение оригинальной англоязычной документации, после чего — либо дополнительные разъяснения, либо часы экспериментов с RewriteLog.
Так что часы экспериментов с RewriteLog решают.
 
Последнее редактирование:
Назад
Сверху