05
декабря
2007

Два примера использования mod_rewrite

За последние год-полтора по русским блогам сильно распространилась фраза про швейцарский нож («[нечто] — это швейцарский нож в [некой области]»). Ничего не имею против Victorinox, но чертовски не люблю злоупотребление заимствованиями и фразы штампы. Когда же в текстах злоупотребляют заимствоваными из другого языка штампами — это вообще ужас. Сразу возникает ощущение, что весь текст — результат работы программы-переводчика.

Но речь сейчас не о Швейцарии и не о русском языке, а (кто бы мог подумать) о модуле веб-сервера Apache mod_rewrite. По этой теме можно найти огромное количество документации, поэтому я не стану подробно излагать особенности функционирования модуля, а лишь приведу свой опыт его использования на конкретных примерах для иллюстрации возможностей.

Еще несколько лет назад mod_rewrite присутствовал не на всех apache-хостингах и при разработке скриптов осмысленным шагом было не расчитывать (если это возможно) на его наличие вообще, либо предусматривать возможность работы программ без его использования. Таким образом обеспечивалась лучшая переносимость и избавить себя от ряда потенциальных проблем при смене хостинговой площадки. Именно так я и поступал до недавнего времени. Но теперь, когда найти хостинг без mod_rewrite достаточно сложно, решил подробнее разобраться с функционированием модуля.

mod_rewrite имеет очень обширные возможности по настройке преобразования URL, из-за чего во многих статьях его сравнивают с тем самым пресловутым швейцарским ножом. Но, как это часто бывает в среде Unix, подобная гибкость порождает малопонятные для неподготовленного пользователя конфигурационные файлы. Несмотря на то, что с используемыми в них регулярными выражениями я в общем-то был знаком, все равно пришлось искать документацию, без которой синтаксис конфигов mod_rewrite понять с ходу не получилось.

Если не вдаваться в детали, работа модуля сводится к последовательной проверке совпадения URL запрашиваемых у сервера страниц и заданных шаблонов. В простейшем случае, модуль может просто проверять их на совпадение, но при необходимости (которая случается весьма часто), можно использовать регулярные выражения для сравнения уже не с жестко заданными строками, а с шаблонами адресов. Кроме того, можно задавать дополнительные условия с использованием переменных окружения сервера. При нахождении нужных совпадений, модуль выдает контент заданной страницы, переадресует HTTP-клиента или выполняет иные заданные действия. Очень удобно выделять с помощью mod_rewrite из URL отдельные параметры и передавать их скрипту CMS. Тогда в самой CMS не придется выполнять дополнительных действий для обработки запросов и проверки их корректности.

Некоторое время назад я обновлял блог и в ходе этого перенес часть контента на новые адреса. При этом, количество посетителей, приходящих по старым ссылкам с поисковиков или через закладки, не изменилось. Показывать всем им ошибку 404 было бы совсем неконструктивным решением, т.к. искомый ими контент не был удален, а лишь сменил местоположение. mod_rewrite очень хорошо подошел для решения подобной типичной задачи.

Перенесенные страницы имели адреса вида /posts/id, где id — числовой идентификатор поста. Требовалось, чтобы сервер переадресовывал всех, кто приходит на эти URL, с домена paradigm.ru на домен goodold.paradigm.ru. Все решилось добавлением в .htaccess одной строки:

RewriteRule ^posts/([0-9]+)$ http://goodold.paradigm.ru/posts/$1 [R,L]

Здесь первый параметр опции RewriteRule — это регулярное выражение, по которому mod_rewrite находит нужные URL. А второй — шаблон URL, по которому в данном случае будет выполнен редирект. То, что необходима именно переадресация определено в третьем параметре, буквой R (L дополнительно сообщает о том, что при срабатывании данного правила, все остальные обрабатывать не нужно). На примере id так же проиллюстрировано, как выделять фрагменты исходного адреса и передавать в новый ($1).

Один нюанс, с которым я столкнулся: парсер регулярных выражений не понял обозначения d+ (последовательность цифровых символов произвольной длины), поэтому пришлось использовать менее лаконичную запись [0-9]+.

Вторым примером использования mod_rewrite было «обучение» Вордпресса понимать короткие адреса постов. Изначально самый короткий вариант ссылки на пост или страницу в этой CMS выглядит как http://example.com/?p=id. Для того, чтобы сделать ссылки более удобными для чтения, можно сократить такие адреса до http://example.com/id (меньше слов понадобится для передачи URL голосом по телефону). Реализуется совсем просто:

RewriteRule ^([0-9]+)$ /?p=$1 [R,L]

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

Ссылки по теме:

oreilly-mastering-regexps1.jpgИ еще: недавно был найден полный текст русского перевода книги тов. Дж. Фридла «Регулярные выражения» (оригинал издан O’Reilly и называется «Mastering Regular Expressions»). Текст официально выложен для общего доступа издательством «Питер»: http://shop.piter.com/library/978531800056/.



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

# Алексей: (4 декабря, 2009 @ 16:37)

ссылка “mod_rewrite Cheat Sheet @ ilovejackdaniels.com” переехала на новый адрес (http://www.addedbytes.com/cheat-sheets/mod_rewrite-cheat-sheet/). Спасибо за статью =)

# admin: (4 декабря, 2009 @ 18:29)

@Алексей: Поправил, спасибо.

# Юрий: (8 января, 2010 @ 04:58)

ножОм несмотря к последовательной проверкЕ “Все решилось добавлением в .htaccess одной строки:” – может, именно поэтому на http://goodold.paradigm.ru/ ссылки на статьи не работают?

# admin: (8 января, 2010 @ 11:34)

Юрий: Спасибо. Что сломалось на goodold, мы посмотрим.

Написать комментарий

Можно использовать следующие HTML теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> .