Loading...
X

Обработка строки параметров URI в mod_rewrite


Запросы: request и query

Чтобы не возникло путаницы, начнём с терминов. В английском языке используются два слова request и query. Проблема в том, что они переводятся одинаково как «запрос». При этом они могут использоваться в одном контексте — в английском языке это не вызывает путаницы, а в русском получается «запрос» и «запрос», которые означают разные вещи.

Слово request относится к HTTP запросу. Протокол HTTP передаёт запрос на сервер, в этом запросе содержаться заголовки (например, информация об интересующем хосте (сайте), User-Agent пользователя, имеющиеся для этого сайта кукиз и прочее). Также говорят об URI запроса, методе запроса и так далее. Среди передаваемой информации также имеется query — строка запроса.

К примеру, если я в веб-браузере открою страницу suay.ru/wp-admin/post.php?post=1673&action=edit, то в ней строкой запроса (query) будет post=1673&action=edit, то есть всё то, что следует после ? (знака вопроса).

Как в mod_rewrite искать по параметрам после знака вопроса

Нужно понимать эту разницу, так как по умолчанию mod_rewrite работает с REQUEST_URI, то есть частью запроса, которая НЕ включает в себя строку query. Причём RewriteRule просто игнорирует query.

Очень часто mod_rewrite используется для ЧПУ («красивых» адресов), когда нужно сделать преобразования вида: из

  • site.com/phones/infos/4/52

в

  • site.com/index.php?category=phones&subcat=infos&idc=4&marea=52

В этом случае, как мы видим, исходная строка не содержит строки запроса (query), поэтому при написании правила проблема игнорирования query не возникает:

RewriteEngine on
RewriteRule ([A-Za-z]+)/([A-Za-z]+)/([0-9]+)/([0-9]+) index.php?category=$1&subcat=$2&idc=$3&marea=$4

А что если нам нужно сделать преобразование другого рода:

Из:

http://site.com/category/infos/pages.php?idc=4&marea=52

В:

http://site.com/category/infos/pages.php?marea=52

То есть мы убираем из строки запроса (query) параметр idc вместе с его значением.

В этом случае мы уже не можем использовать RewriteRule, поскольку его правила полностью игнорируют строку query. Правда, используя некоторые флаги можно сделать так, чтобы исходная строка запроса query добавлялась к новому URI — но нам в рассматриваемой ситуации нужно не это.

Проблема решается с использованием директивы RewriteCond, которая умеет работать с переменной QUERY_STRING, содержащей строку query с запросом.

Что нам нужно знать про RewriteCond? Директива RewriteCond оказывает воздействие на RewriteRule, которое следует после строки (или блока строк) RewriteCond. В RewriteCond также можно использовать обратные ссылки, но для разграничения от обратных ссылок RewriteRule, вместо $ (знака доллара) используется % (знак процента), то есть вместо $1, первая обратная ссылка обозначается как %1.


Итак, составляем RewriteCond для нашего случая:

RewriteCond "%{QUERY_STRING}" "idc=([0-9]+)&marea=([0-9]+)$"

Рассмотрим эту строку подробно.

%{QUERY_STRING} означает, что анализируется строка запроса, следующая в URI после знака вопроса.

Строка idc=([0-9]+)&marea=([0-9]+)$ представляет собой шаблон поиска. То есть ищется строка, которая начинается на idc=, затем следуют цифры (одна или более) — причём, поскольку это регулярное выражение в скобках, то найденные цифры помещаются в первую обратную ссылку, затем идёт строка &marea=, затем опять цифры (одна или более), причём найденные цифры помещаются во вторую обратную ссылку. В данном случае символ $ означает конец анализируемой строки.

Чего мы этим добились? Мы сделали так, что значение idc будет помещено в первую обратную ссылку, а значение marea будет помещено во вторую обратную ссылку.

Переходим непосредственно к правилу перезаписи RewriteRule:

RewriteRule "(.*)" "/$1?marea=%2" [L,R]

Рассмотрим это содержимое подробно:

Регулярное выражение (.*) означает «что угодно». Но мы помним, что это «что угодно» игнорирует строку запроса query. То есть это URI без строки query. Причём, поскольку это регулярное выражение в скобках, то оно помещается в первую обратную ссылку.

Далее строка /$1?marea=%2. Она начинается с указания на корневую папку сайта (/), затем идёт первая обратной ссылка $1, в неё помещается весь URI кроме строки запроса, затем добавляется строка ?marea=, к которой добавляется то, что содержится во второй обратной ссылке (%2) от RewriteCond.

Флаги [L,R] означают завершить проверку по другим правилам и сделать редирект на новый адрес (то есть адрес страницы измениться в адресной строке веб-браузера пользователя).

В результате получится, что адрес:

  • http://site.com/category/infos/pages.php?idc=4&marea=52

Превратится в:

  • http://site.com/category/infos/pages.php?marea=52

Соберём условие перезаписи и правило перезаписи вместе:

RewriteEngine on
RewriteCond "%{QUERY_STRING}" "idc=([0-9]+)&marea=([0-9]+)$"
RewriteRule "(.*)" "/$1?marea=%2" [L,R]

Как с mod_rewrite удалить параметр из URI

Эта конструкция приводит к тому, что будет «вырезано» значение определённого параметра из получаемой строки запроса. Если говорить более точно, строка запроса будет заново пересобрана, но уже без одного из своих параметров. Используя эту технику можно убирать один или несколько параметров из запроса, либо присваивать их значения другим параметрам.

Ничего не поняли? Значит начните изучение mod_rewrite с самых основ. Подробный учебник по mod_rewrite на русском языке здесь.

Рекомендуется вам:


Leave Your Observation

Ваш e-mail не будет опубликован. Обязательные поля помечены *

wp-puzzle.com logo

Scroll Up