Академия mod_rewrite. Урок 1: первое правило и как оно работает

Добро пожаловать в «Академию mod_rewrite» — пятиурочный курс, который ведёт от первого правила до сборки полноценного .htaccess. Каждый урок содержит упражнения: вы проверяете себя самостоятельно в тестере RewriteRule. В этом уроке разберём, что такое mod_rewrite, чем перезапись отличается от редиректа, и напишем своё первое правило.

Урок 1 из 5 · следующий → · оглавление курса

Что такое mod_rewrite

mod_rewrite — модуль Apache, который перехватывает входящий запрос и переписывает URL «на лету», до того как сервер решит, какой файл отдавать. Для пользователя и браузера это происходит прозрачно.

Два режима работы:

  • Внутренняя перезапись — путь меняется только внутри сервера. Браузер ничего не узнаёт: адрес в адресной строке остаётся прежним. Так делают «красивые» ЧПУ-адреса: /blog/5 обрабатывается как /post.php?id=5, но пользователь видит /blog/5.
  • Внешний редирект (флаг [R]) — сервер отвечает кодом 301 или 302 и заголовком Location:. Браузер получает ответ и сам переходит по новому адресу — адрес в строке меняется. Так делают постоянные редиректы при переезде страниц.

Если нужны только простые статичные редиректы без условий, mod_rewrite не обязателен — подойдёт Redirect 301 /old /new из модуля mod_alias. mod_rewrite нужен, когда есть условия, захваты групп, сложная логика.

RewriteEngine On и где живёт .htaccess

Файл .htaccess — конфигурационный файл Apache, который читается при каждом запросе к файлам в соответствующем каталоге. Он лежит в корне сайта (или в подкаталоге, если правила нужны только там).

Первая обязательная строка любого rewrite-блока:

.htaccessкопировать
RewriteEngine On

Без неё все RewriteRule и RewriteCond молча игнорируются — это причина №1 «правила не срабатывают». Ставьте её в начало блока правил в каждом .htaccess, где есть свои rewrite-правила.

RewriteBase — нужна, если .htaccess лежит в подкаталоге и вы используете относительные подстановки. Например, если сайт доступен как https://example.com/shop/, а .htaccess лежит в каталоге /shop/:

.htaccessкопировать
RewriteEngine On
RewriteBase /shop/

Если .htaccess в корне сайта и все подстановки абсолютные (начинаются с /), RewriteBase не нужна.

Первое правило RewriteRule

Синтаксис: RewriteRule Паттерн Подстановка [Флаги].

Разберём конкретное правило — постоянный редирект со старой страницы на новую:

.htaccessкопировать
RewriteEngine On
RewriteRule ^old\.html$ /new.html [R=301,L]

По частям:

  • Паттерн ^old\.html$ — регулярное выражение, которое сопоставляется с путём запроса. В .htaccess в корне сайта путь подаётся без ведущего /: запрос /old.html → паттерн видит old.html. Символы ^ и $ — якоря: «начало» и «конец» строки. \. — экранированная точка (буквальная), иначе . в regex означает «любой символ».
  • Подстановка /new.html — во что превратить адрес. Начинается с / — абсолютный путь на сервере.
  • Флаги [R=301,L] — через запятую в квадратных скобках. R=301 — внешний редирект с кодом 301 (постоянный). L — «last», остановить обработку правил на этом шаге.

Теперь пример внутренней перезаписи — «красивый» URL для блога без изменения адреса в браузере:

.htaccessкопировать
RewriteEngine On
RewriteRule ^blog/(\d+)$ /post.php?id=$1 [L]

(\d+) — группа захвата: одна или больше цифр. $1 в подстановке — это то, что захватила группа (номер поста). Флага [R] нет — значит это внутренняя перезапись, браузер адрес не видит.

Как Apache читает правила

Apache обрабатывает правила в .htaccess сверху вниз. Каждое подходящее RewriteRule изменяет текущий URL; если не было флага [L], обработка продолжается со следующего правила.

Что делает флаг [L] — «last»: останавливает текущий проход через набор правил. Без него правила «текут» дальше и следующие могут применяться к уже изменённому URL.

Важная тонкость: в контексте .htaccess после того как URL изменился, Apache может запустить весь набор правил заново с новым URL — до тех пор, пока URL не перестанет меняться. Поэтому [L] — это «конец текущего прохода», а не «больше никогда». Для окончательной остановки используют флаг [END] (Apache 2.4+).

Упрощённо: пишите правила в порядке «сначала редиректы, потом перезаписи», ставьте [L] там, где обработка должна остановиться.

Попробуй сам

Откройте тестер RewriteRule, вставьте любое из правил выше, введите тестовый URL и нажмите «Проверить». Вы увидите пошаговую трассировку: какое правило сработало, какие условия прошли, во что превратился адрес и итог.

Упражнения

  1. Напишите правило, которое делает постоянный редирект (301) с /contacts.html на /contacts.
    Подсказка: паттерн без ведущего /, используйте [R=301,L].
    Проверьте себя в тестере RewriteRule.
  2. Напишите правило, которое при запросе /team внутренне отдаёт /team.php — без изменения адреса в браузере.
    Подсказка: флага [R] быть не должно.
    Проверьте в тестере RewriteRule.
  3. Что произойдёт, если убрать флаг [L] из правила, когда ниже есть ещё одно правило?
    Подсказка: обработка продолжится со следующего правила, уже применяя его к изменённому URL.

Что дальше

В уроке 2 разберём все ключевые флаги RewriteRule подробно: постоянный и временный редирект, [QSA], [NC], блокировки [F]/[G], цепочки правил.