интернет :: разное

Модуль mod_rewrite, или выдаем желаемое за действительное

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

Все, наверное, хотят иметь свой сайт — если не каждый интернетчик, то большинство, как ни крути. Конечно, можно пойти простым путем, сделав на бесплатном хостинге пару HTML-страничек, и любоваться своим “произведением искусства”, показывая его всем друзьям и думая, что уже достиг совершенства в веб-мастеринге. Но мы ведь не такие. Мы уже знаем, что такое PHP, MySQL и прочие модные слова, которыми пестрит весь Интернет. А еще мы уже умеем немного программировать на PHP и создавать простые скрипты как минимум. Кто еще не умеет этого делать — быстренько покупаем какой-нибудь самоучитель по PHP или читаем предыдущие выпуски КГ со статьями Андрея Кухарчика. Так вот, будем считать, что уровень подготовки в данном вопросе у тебя выше среднего, и ты сам можешь написать простенький скрипт управления сайтом.

Итак, ты уже имеешь твердое решение создать себе сайт, у тебя есть для этого набор скриптов, и ты почти счастлив. А почти, потому что для полноты ощущений тебе не достает сущей мелочи. Тебе не хватает красивых ссылок на страницы твоего сайта. Ведь, делая сайт на HTML, мы получали готовые странички, и на сайте это выглядело как http://www.fedja_brusnikin.narod.ru/god.html , а сделав сайт на PHP, разместив его уже на платном хостинге и купив красивое имя на домене второго уровня, мы получаем теперь http://www.brusnikincompany.com/home/index.php?article1 . В первом случае у нас была довольно конкретная ссылка с именем файла god.html, а теперь получаем некий абстрактный путь. Надо что-то делать, дабы иметь до конца солидный облик в Интернете. Но реализация языка PHP не позволяет этого сделать обычными средствами. Вернее, не сам язык, а непосредственно подход при создании сайтов на его основе. Почему так получается, пояснять не буду, а как этого избежать — расскажу. Для этого нужен только хостинг, работающий под сервером Apache, и модуль для этого самого Apache, именуемый mod_rewrite (теперь-то ты понял, что это за зверь;)). Mod_rewrite является замечательным модулем, который предоставляет «основанный на правилах механизм динамического изменения запрашиваемых URL'ов». Это действительно мощный инструмент, и поэтому его знание принципиально важно, если ты хочешь стать подлинным веб- мастером или веб-программистом. Любой уважающий себя хостинг имеет в своем распоряжении эти вещи. Модуль mod_rewrite поставляется с Apache, и для его включения надо всего лишь раскомментировать строку в файле настроек и перезапустить Apache (думаю, тут у тебя не возникнет никаких проблем;)). Итак, все вышеописанные инструкции выполнены, и модуль установлен. Перейдем к делу.

Все веб-мастера видели, наверное, файл .htaccess. Так вот, тем, кто его все-таки не видел, поясняю. Файл .htaccess является мини-файлом настроек веб-сервера Apache. Это значит, что настройки, указанные в этом файле, будут перекрывать или дополнять основные настройки сервера, но только применительно к конкретной директории и ее поддиректориям. Звучит слишком умно и непонятно? А на самом деле все очень просто. К примеру, сайт наш находится у хостера в папке htdocs_html. По умолчанию сервер сканирует директорию на наличие файла index.html и, найдя его, отдает на растерзание браузеру. Но вдруг нам надо, чтобы основным файлом был, например, main.html. Все просто. Создаем файл .htaccess, в котором пишем: 
DirectoryIndex main.html index.html index.php

И вот в такой вот последовательности и будет сканироваться директория. То есть, если нет файла main.html, то будет искаться index.html, а если и его нет, то index.php. Ну, я думаю, это знали многие. Теперь, если говорить по теме статьи, нам надо привести ссылки на сайте в удобочитаемый вид. Для этого нужно опять создавать файл .htaccess (если его еще нет). В конец файла смело дописывай следующие строки: 
RewriteEngine on
Options +FollowSymlinks

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

Если тебе вдруг понадобилось разместить сайт в другой директории — например, /forum — то просто пишешь:

RewriteBase /forum

Теперь надо настроить некоторые правила обработки ссылок на твоем сайте. Но начнем мы с защиты самого файла .htaccess. Дело в том, мой друг, что не все хостеры додумываются блокировать доступ к этому файлу, потому действуй по принципу “защити себя сам”. Для этого далее добавляем в файл строку:

RewriteRule ^.htaccess$ — [F]

Отлично. Теперь ты защитил себя от лишних глаз. Вкратце ты сделал вот что. Если какой-то умный хакер Вася из соседней квартиры решит посмотреть настройки твоего сервера, набрав http://www.brusnikincompany.com/.htaccess, то ничего у него не выйдет. А вместо этого он увидит ошибку 403 (Доступ запрещен). Само правило представляет собой регулярное выражение и флажок действия. ^ — якорь начала строки, $ — якорь конца строки, а . (точка) — метасимвол. Между этой конструкцией расположено имя файла. Это для того, чтобы другой файл не вызывал ошибку. Ну, а флажок действия [F] указывает, что на это правило должен выполняться запрет 403. Получаем файл со следующим содержимым:

DirectoryIndex main.html index.html index.php
RewriteEngine on
Options +FollowSymlinks
RewriteBase /
RewriteRule ^.htaccess$ — [F]

Однако, помимо правил, которые обозначаются директивой RewriteRule, есть еще и условия, после которых выполняется данное правило. Имя этой директиве — RewriteCond. Одним словом, мы можем ограничивать «правило» при помощи различных «условий правила». «Правило» будет выполнено только в том случае, если перед ним будет встречен ряд условий.

Пример такого файла может быть следующим:
RewriteEngine on
Options +FollowSymlinks
RewriteBase /
RewriteCond %{HTTP_USER_AGENT} ^OfflineExplorer
RewriteRule ^.*$ — [F]

Тут все понятно. Надо только пояснить назначение четвертой строки. Эта строка является условием, по которому будет выполняться правило из строки 5. Это условие запрещает доступ программе Offline Explorer к твоему сайту. Вначале идет так называемая проверочная переменная вида %{ИМЯ ПЕРЕМЕННОЙ}, а затем — условие в виде регулярного выражения. Что такое регулярные выражения — это тема целых книг, потому я в нескольких строках попробую показать, что они собой представляют, а дальше ищите материалы в открытых источниках.

Регулярные выражения — это обыкновенный шаблон, по которому производится поиск в определенной строке. Наверное, ты знаешь, что, если в поиске большинства программ набрать символ “*”, то будет произведен поиск любого количества символов вместо подставного, а если поставить символ “?”, то будет искаться любой один символ. Например, это часто используется в поиске файловых менеджеров. Написав в поиске “*.txt”, мы ищем только текстовые файлы, а написав “*.php?” — соответственно php-скрипты всех версий и т.д. 

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

. (точка) — текст (любой символ);
| — чередование (то есть /abc|def/);
* — квантификатор (разрешено любое число);
^ $ — якоря строки;
s — оператор (string1 заменить на string2);
g — модификатор (искать по всему тексту).

В данном случае мы написали “^OfflineExplorer”. Это значит, что строка должна начинаться ТОЛЬКО со слова OfflineExplorer, а что будет дальше, неважно. Это может быть и OfflineExplorer_3_0, и OfflineExplorer_3_5_pro и т.д. В данном случае мы не поставили символ “$”, который бы закрывал строку. Аналогично и с правилом для имени файла. “^” открывает стоку, “.” — указывает на использование в имени любого символа, “*” — означает, что любой символ может повторяться сколько угодно раз, и “$” — закрывает строку. Получается, мы можем использовать ЛЮБОЕ имя файла в данном правиле.

Но если ты хочешь, чтобы твой сайт не мог атаковать не только OfflineExplorer, но, к примеру, и TeleportPro, то .htaccess-файл будет выглядеть так:

RewriteEngine on
Options +FollowSymlinks
RewriteBase /
RewriteCond %{HTTP_USER_AGENT} ^Teleport [OR]
RewriteCond %{HTTP_USER_AGENT} ^OfflineExplorer
RewriteRule ^.*$ — [F]

Флаг [OR] обозначает условие “или”, то есть мы не дадим лазить по сайту OfflineExplorer и TeleportPro. Если этот флаг не стоит, действует условие “и”. Также можно вставлять флаг [NC], который делает условие нечувствительным к регистру. Выглядит это так:

RewriteCond %{HTTP_USER_AGENT} ^tElEpOrT [OR, NC]

Кроме “HTTP_USER_AGENT”, можно использовать переменные “REMOTE_HOST” и “REMOTE_ADDRESS”.
Например, условие:

RewriteCond % {REMOTE_HOST} ^www.host.ru$
RewriteRule ^.*$ — [F]

блокирует все запросы с хоста “www.host.ru”.
Аналогично

RewriteCond %{REMOTE_ADDR} ^192.168.0.
RewriteRule ^.*$ — [F]

блокирует целую подсеть.

Итак, теперь ты знаешь, как ограничить свой сайт от всяких спамеров, “качалок” и плохих посетителей. Теперь надо разобраться, как делать “красивые” ссылки. Итак, у тебя есть сайт и ссылки вида:

http://www.brusnikincompany.com/home/index.php?article1 
http://www.brusnikincompany.com/home/index.php?article2
http://www.brusnikincompany.com/home/index.php?article3
и т.д.

Сделаем, чтобы ссылки были вида http://www.brusnikincompany.com/articles/article1, не меняя сильно работы скриптов сайта. Пишем:

RewriteEngine on
Options +FollowSymlinks
RewriteBase /
RewriteRule ^(.*)articles /(.*)$ $1home/index.php?$2

Как ты видишь, тут есть две интересные позиции: $1 и $2. Это метки, которые связаны с текстовыми группами. Вызываемый URL разбивается на части. Все, что находится перед articles, плюс все, что находится после articles/, определяется и хранится в этих двух переменных ($1 и $2). В общем виде замена URL выглядит вот как:

RewriteRule настоящийURL перезаписываемыйURL

В этом случае и поисковику, и пользователю будет удобно понимать такие ссылки. Однако это всего лишь основы работы с модулем mod_rewrite. Если ты хочешь действительно сделать стоящий сайт, чтобы ссылки на нем действительно выглядели красиво, понятно и грамотно, то нужно уже заранее предусмотреть работу с самой CMS, работу ее разделов, категорий и т.д. Как вариант можно посмотреть на работу CMS у студии e.motion ( сайт ). В этой CMS как раз и организованы понятные человеку ссылки, которые генерируются динамически и четко показывают ему, где он находится на сайте. Аналогичные функции реализованы у многих систем управления сайтом. Например, если не лень разобраться в исходном коде Mambo CMS ( сайт ), то можно будет понять, как работает перезапись ссылок в этой Open Source системе. Также сам модуль mod_rewrite неплохо задокументирован в документации к серверу Apache ( сайт ). И тебе было бы неплохо для начала почитать материалы на сайте SiteMaker ( сайт ).
Вопросы по статье жду на форуме Web-программирование ( сайт ).



Сергей Жуковский, Codeby.net team

© компьютерная газета