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

Тема в разделе "Mod Rewrite / htaccess / ЧПУ", создана пользователем lag, 7 апр 2015.

  1. lag

    lag

    Регистр.:
    13 окт 2014
    Сообщения:
    218
    Симпатии:
    282
    Атрибут 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]
    
     
    svfolder, Q_BASIC и UJy нравится это.
  2. UJy

    UJy

    Регистр.:
    23 авг 2011
    Сообщения:
    373
    Симпатии:
    132
    Проблема насущная. Я тоже не люблю каноникалов и стараюсь всё зарезать, но от твоих правил просто диву даюсь.
    Ты где учился такие конструкции ваять? Есть какой-нить небольшой курс по ваянию такого?
     
    Q_BASIC нравится это.
  3. Q_BASIC

    Q_BASIC

    Регистр.:
    30 ноя 2013
    Сообщения:
    411
    Симпатии:
    288
    Я тоже коду lag'а удивляюсь. Спрашиваешь - все отвечают или громоздким кодом или вообще не тем. А у него любая ситуация разрешима изящно, быстро и коротко, без всякой ерундятины
     
  4. lag

    lag

    Регистр.:
    13 окт 2014
    Сообщения:
    218
    Симпатии:
    282
    Очень хорошая книга "Регулярные выражения" автор Джеффри Фридл.

    Еще подумал тут возможен конфликт с другими правилами которые перезаписывают параметры вроде 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]
    
     
    Последнее редактирование: 7 апр 2015
    UJy нравится это.
  5. UJy

    UJy

    Регистр.:
    23 авг 2011
    Сообщения:
    373
    Симпатии:
    132
    В книге есть раздел сугубо по htaccess? Насколько я понимаю, чисто знание регулярок не слишком то поможет в составлении "таких" правил. Полюбому есть свод правил по работе в htaccess, а регулярки лишь метода отлова урлов.

    Ну либо я сильно ошибаюсь в своих пониманиях htaccess - поправьте меня, если это так.
     
  6. lag

    lag

    Регистр.:
    13 окт 2014
    Сообщения:
    218
    Симпатии:
    282
    В книге среди прочего есть про библиотеку PCRE, которая используется Apache и PHP.
    А про .htaccess точно подмечено в статье Перейти по ссылке
    Так что часы экспериментов с RewriteLog решают.
     
    Последнее редактирование: 7 апр 2015
    latteo нравится это.