URL rewriting для чайников (Часть 2)

Вот и дошли у меня руки дописать статью, которую я начал еще в прошлом году. Для тех, кто не в курсе, рекомендую сначала ознакомиться с первой частью. Ну, поехали.

Сопоставление с шаблоном

Я думаю вы уже заметили в рассмотренных правилах URL rewriting символы ^ и $, ими обернут изменяемый УРЛ. Они необходимы для того, чтобы обернутый ими URL стал шаблоном, на техническом языке это называется Perl Compatible Regular Expression (PCRE) или просто regexp (регулярное выражение). Я называю это шаблоном. Что же такое, эти шаблоны? Допустим, я попрошу вас написать дату своего рождения , вы естественно мне напишите по разному — 02.12.1989 или 02 декабря 1989… А если я вас попрошу о том же самом, но добавлю » в виде ДД.ММ.ГГГГ«, вы все напишите одинаково!Это не совсем описание регулярного выражения (шаблона), но идея именно такая — использовать некие символы которые определяют структуру.

Нам уже встречались два символа шаблонов:

  • ^ — соответствует началу строки;
  • ; — соответствует концу строки;

Если наш шаблон начинается с символа ^ и заканчивается символом $, это говорит нам о том, что мы изменяем URL адрес целиком, а не какую то его часть. Так же существуют другие символы в регулярных выражениях:

  • [0-9] — соответствует целому ряду чисел. Например [2-4] будет соответствовать числам от 2 до 4 включительно.
  • [a-z] — соответствует всем буквам в нижнем регистре.
  • [A-Z] — соответствует всем буквам в верхнем регистре.
  • [a-z0-9] — соответствует всем цифрам и буквам в нижнем регистре.

Это, так называемые, группы символов. Квадратные скобки сообщают серверу, что мы ищем те символы, которые находятся в них. В квадратные скобки вы можете заключать, как конкретные символы, так и диапазон символов. Тем не менее, такая конструкция соответствует только одному символу. К примеру имеем шаблон [0-9], под этот шаблон попадает число 8, а число 84 уже нет. Чтобы искать соответствие двузначному числу, мы должны записать [0-9] дважды — [0-9][0-9]. Таким образом, чтобы найти 1984, нужно написать [0-9][0-9][0-9][0-9]. Но такая конструкция выглядит глупо и громоздко, еще более глупо она будет выглядеть, когда нам понадобится искать соответствия десятизначным числам. Ее можно заменить следующим образом:

[0-9]{10} -В данном случае, мы говорим серверу, что хотим найти число состоящее из 10 цифр в диапазоне от 0 до 9.

Если нам нужно найти какое либо число, но мы не знаем сколько цифр оно содержит (например идентификатор базы данных в УРЛ), мы можем использовать символ +. Он означает один или более. Шаблону типа [0-9]+ будет соответствовать, как 1,234 так и 1234.

Попробуем на практике.

Допустим мы имеем со статьями, URL адреса которых имеют структуру вида «/2013/nazvanie-stati/», нам нужно, чтобы все они были доступны по адресу «/stati.php» .

Давайте разберем начальный адрес страниц: каждая статья в адресе имеет год (число из 4 цифр), слэш, название статьи на латинице (может содержать буквы, цифры и знак «-») и еще один слэш. Шаблон (регулярное выражение) будет выглядеть следующим образом:

^[0-9]{4}/[a-z0-9-]+/$

Выглядит непонятно, но это пока. Давайте в нем разбираться. В начале (^) мы ищем четырехзначное число ([0-9]{4}), затем слэш (/) — это просто символ, далее набор букв в нижнем регистре, цифр и тире ([a-z0-9-]), сколько именно символов нам встретится, мы не знаем (+), и весь адрес заканчивается слэшем (/$). На основании этого шаблона создадим правило URL rewrite:

RewriteRule ^[0-9]{4}/[a-z0-9-]+/$ /stati.php

Мы почти на финише! На данный момент мы можем перенаправлять URL адреса статей на адрес stati.php, главное чтобы этот файл знал какую статью нужно отобразить.

Захват группы и замена.

Зачастую, при перенаправлении URL адресов нам необходимо взять какие либо части адреса и передать их скрипту, который обработает запрос. Это делается, путем добавления этих частей в виде параметров. В нашем случае, нужно быть уверенным, что скрипт знает год и название статьи. Следовательно, URL адрес должен выглядеть примерно так:

/stati.php?year=2013&slug=nazvanie-stati

Чтобы перенаправить на такой адрес, а заодно передать параметры, нам нужно будет пометить части старого URL адреса, чтобы использовать в новом. Делается это с помощью круглых скобок. Размещая круглые скобки в шаблоне, мы группируем необходимые для нас данные. Теперь наше регулярное выражение будет выглядеть таким образом:

^([0-9]{4})/([a-z0-9-]+)/$ 

Для использования сгруппированных данных в новом УРЛ адресе необходимо написать символ $ и номер группы, которую хотим подставить. Таким образом, первая группа из нашего регулярного выражения будет вызываться посредством $1, а вторя $2 (во второй половине правила URL rewriting символ $ не сообщает о конце строки).

RewriteRule ^([0-9]{4})/([a-z0-9-]+)/$ /stati.php?year=$1&slug=$2 

Значение года присваивается с помощью $1, а название статьи $2. Если бы была третья группа, ее значение присваивалось бы с помощью $4 и так далее. В языке регулярных выражений, это называется обратной ссылкой.

Опции

В самом начале статьи вы могли заметить в структуре правил URL rewriting обозначение опций. Наиболее используемые, да и вообще, часто встречающиеся (на мой взгляд), следующие опции:

  • R=301 — эта опция говорит пользователю и поисковой система, что страница навсегда перемещена на новый УРЛ адрес. Таким образом, мы указываем поисковой системе обновить индекс.
  • L — Last. Данный флаг останавливает выполнение других правил URL rewriting, эту нужно для того чтобы адрес дальше не менялся.

Есть конечно и другие опции (флаги), но расписывать их работу, я не вижу смысла. Если есть желание, можете ознакомиться с ними тут.

Опции задаются в квадратных скобках в конце правила URL rewriting. Вы можете написать в квадратных скобках несколько флагов, разделив их запятыми.

RewriteRule ^([0-9]{4})/([a-z0-9-]+)/$ /stati.php?year=$1&slug=$2 [L]

или

RewriteRule ^about/([a-z0-9-]+).jsp/$ /about/$1/ [R=301,L]

Вот в принципе и все, что я хотел вам рассказать про правила mod_rewrite. Надеюсь, что многое теперь стало понятно и вы, получив 500 ошибку сервера, сможете проанализировать проблему.

Добавить комментарий

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