Директива RewriteRule и есть настоящая рабочая лошадка преобразований. Эта директива может встречаться более одного раза. Каждая директива, в этом случае, определяет одно правило преобразования. Порядок определений этих правил важен, потому что этот порядок используется при обработке правил во время работы.
Шаблон это perl совместимое регулярное выражение которое применяется к текущему URL. Здесь под «текущим» подразумевается значение URL когда применяется это правило. Этот URL не обязательно совпадает с первоначально запрошенным URL, потому что любое количество правил возможно уже были применены к нему и соответственно преобразовали его.
Некоторые указания по синтаксису регулярных выражений:
Текст: . Любой одиночный символ [chars] Класс симвлолв: Один из символов [^chars] Класс симвлолв: Ни один из символов text1|text2 Альтернатива: text1 или text2 Кванторы (символы для обозначения количественных отношений): ? 0 или 1 из предшествующего текста * 0 или N из предшествующего текста (N > 0) + 1 или N из предшествующего текста (N > 1) Группировка: (text)Группировка текста (либо установка границ альтернативы или для создания обратных связей где N группа, которая может быть использована в RHS директивы RewriteRule с $N) Маркеры: ^ Маркер начала строки $ Маркер конца строки Экранирование: charэкранирование конкретного символа (к примеру для указания символов «.[]()» и т.д.)
Более подробную информацию о регулярных выражениях, смотрите в документации по регулярным выражениям Perl («perldocperlre»). Если вы заинтересованы в ещё более детальной информации о регулярных выражениях и их диалектах (POSIX и т.д.), смотрите следующую, специально написанную по этой теме книгу:
Mastering Regular Expressions
Jeffrey E.F. Friedl
Nutshell Handbook Series
O’Reilly & Associates, Inc. 1997
ISBN 1-56592-257-3
Кроме того, в mod_rewrite символ отрицания (NOT) (‘!’) — допускаемый префикс в шаблоне. Это даёт вам возможность инвертировать действие шаблона; ну к примеру скажем: «если текущий URLне совпадает с этим шаблоном». Это может быть использовано в особых случаях, когда проще найти шаблон для несоответствия, или в качестве последнего правила, работающего по умолчанию.
Примечание
При использовании символа NOT (не) для инвертирования действия шаблона вы не можете иметь сгруппированные части групповых символов в шаблоне. Это невозможно потому что когда нет соответствия шаблону, для групп нет никакого содержимого. В результате, если используются шаблоны с отрицанием, вы не можете использовать $N в строках подстановок!
Подстановка в правиле преобразования это строка будет подставляться (или будет заменять) вместо оригинального URL, для которого естьсовпадение Шаблону. Кроме простого текста вы можете использовать
Обратные связи это $N(N=0..9) идентификаторы которые заменяются содержимым N-й группы подходящего Шаблона. Переменные сервера Это тоже самое что и СравниваемаяСтрока директивы RewriteCond. Запросы к массиву пришли из директивы RewriteMap там они и объяснены. Эти три типа переменных рассматриваются в порядке, в котором они идут в вышеприведенном списке.
Как уже было упомянуто выше, все правила преобразований применяются с использованием Подстановки (в порядке, в котором они определены в конфигурационном файле). URL полностью заменяется Подстановкой и процесс преобразования идет до тех пор, пока не останется больше никаких правил, если только он не прерван специально, с помощью флага L — см. ниже.
Существует специальная строка подстановки вида ‘-‘ которая означает: НЕТ подстановки! Звучит глупо? Нет, это полезно для правил преобразования которые только проверяют некоторые URL однако не производят подстановок, т.е., в связке с флагом C (цепочка) возможно иметь более чем один шаблон, применяемый перед проведением непосредственно самой подстановки.
Ещё одно замечание: Вы даже можете создавать URL, содержащие строку запроса, в строке подстановки. Просто используйте вопросительный знак внутри строки подстановки для указания того, следующее за ним содержимое должно быть преобразовано в QUERY_STRING (строку запроса). Когда вы хотите убрать существующую строку запроса, завершайте строку подстановки просто вопросительным знаком.
Примечание
Есть одна особенность: Когда вы предваряете поле подстановки строкой http://thishost[:thisport], — mod_rewrite отрезает её автоматически. Это автоматическое усечение подразумеваемое при внешнем редиректе URL полезная и важная особенность при использовании в связке с запросами к массивам преобразований генерирующих имя хоста. Взгляните на первый пример, в разделе примеров ниже, чтобы понять это.
Помните
Безусловный внешний редирект на ваш собственный сервер не будет работать с префиксом http://thishost из-за этой особенности. Чтобы использовать такой саморедирект, Вы должны использовать флаг R(см. ниже).
В подстановке вы можете использовать, в том числе, и специальные флаги путем добавления следующей конструкции:
[флаги]
в качестве третьего аргумента директивы RewriteRule. Флаги — это разделённый запятыми, следующий список флагов:
Примечание
Никогда не забываёте что Шаблон применяется ко всему URL в конфигурационных файла сервера. Однако в конфигурационных файлах каталогов, префикс каталога (который всегда одинаков для конкретного каталога !), автоматически удаляется при соответствии шаблону и автоматически добавляется после завершения подстановки. Эта особенность, основа для многих видов преобразований, потому что без удаления префикса для родительского каталога тоже должно быть соответствие, что не всегда возможно.
Есть одно исключение: Если строка подстановки начинается с «http://» в этом случае префикс каталога не добавляется и происходит либо внешний редирект либо пропускание через прокси (если используется флаг P!)!
Примечание
Для того чтобы включить механизм преобразований в конфигурационных файлах каталогов вам нужно написать «RewriteEngine On» в этих самых файлах и, кроме того, должна быть разрешена конфигурационная директива «Options FollowSymLinks». Если ваш администратор запретил перегрузку конфигурационной директивы FollowSymLinks в пользовательских каталогах, в этом случае вы не сможете использовать механизм преобразований. Это ограничение нужно по соображениям безопасности.
Вот все возможные комбинации подстановок с расшифровкой их значений:
В конфигурационных файлах контекста сервера (httpd.conf)
для запроса вида «GET /somepath/pathinfo»:
Правило Подстановка ———————————————- ———————————- ^/somepath(.*) otherpath$1 не поддерживается, т.к. неверно! ^/somepath(.*) otherpath$1 [R]не поддерживается, т.к. неверно! ^/somepath(.*) otherpath$1 [P]не поддерживается, т.к. неверно! ———————————————- ———————————- ^/somepath(.*) /otherpath$1 /otherpath/pathinfo ^/somepath(.*) /otherpath$1 [R]http://thishost/otherpath/pathinfo через внешний редирект ^/somepath(.*) /otherpath$1 [P]не поддерживается, — глупо! ———————————————- ———————————- ^/somepath(.*) http://thishost/otherpath$1/otherpath/pathinfo ^/somepath(.*) http://thishost/otherpath$1 [R] http://thishost/otherpath/pathinfo через внешний редирект ^/somepath(.*) http://thishost/otherpath$1 [P] не поддерживается, — глупо! ———————————————- ———————————- ^/somepath(.*) http://otherhost/otherpath$1 http://otherhost/otherpath/pathinfo через внешний редирект ^/somepath(.*) http://otherhost/otherpath$1 [R] http://otherhost/otherpath/pathinfo через внешний редирект (флаг [R] избыточен) ^/somepath(.*) http://otherhost/otherpath$1 [P] http://otherhost/otherpath/pathinfo через внутренний прокси
Внутри конфигурационного файла каталога, для /somepath
(т.е., файл .htaccess в каталоге /physical/path/to/somepath содержит RewriteBase /somepath)
для запроса «GET /somepath/localpath/pathinfo»:
Правило Подстановка ———————————————- ———————————- ^localpath(.*) otherpath$1 /somepath/otherpath/pathinfo ^localpath(.*) otherpath$1 [R]http://thishost/somepath/otherpath/pathinfo через внешний редирект ^localpath(.*) otherpath$1 [P]не поддерживается, — глупо! ———————————————- ———————————- ^localpath(.*) /otherpath$1 /otherpath/pathinfo ^localpath(.*) /otherpath$1 [R]http://thishost/otherpath/pathinfo через внешний редирект ^localpath(.*) /otherpath$1 [P]не поддерживается, — глупо! ———————————————- ———————————- ^localpath(.*) http://thishost/otherpath$1/otherpath/pathinfo ^localpath(.*) http://thishost/otherpath$1 [R] http://thishost/otherpath/pathinfo через внешний редирект ^localpath(.*) http://thishost/otherpath$1 [P] не поддерживается, — глупо! ———————————————- ———————————- ^localpath(.*) http://otherhost/otherpath$1 http://otherhost/otherpath/pathinfo через внешний редирект ^localpath(.*) http://otherhost/otherpath$1 [R] http://otherhost/otherpath/pathinfo через внешний редирект (флаг [R] избыточен) ^localpath(.*) http://otherhost/otherpath$1 [P] http://otherhost/otherpath/pathinfo через внутренний прокси
Пример:
Мы хотим преобразовать URL вида
/ Language /~Realname /…/ File
в
/u/ Username /…/ File . Language
Мы берем файл, содержащий ассоциативный массив для преобразований, приведённый выше и сохраняем его под именем /path/to/file/map.txt. Затем, нам нужно только добавить следующие строчки в конфигурационный файл сервера Apache:
RewriteLog /path/to/file/rewrite.log RewriteMap real-to-user txt:/path/to/file/map.txt RewriteRule ^/([^/]+)/~([^/]+)/(.*)$ /u/${real-to-user:$2|nobody}/$3.$1
Директива RewriteBase
Описание: Устанавливает базовый URL для преобразований в каталоге Синтаксис: RewriteBase directory-path Значение по умолчанию: physical-directory-path Контекст: directory, .htaccess Статус: Расширение Модуль: mod_rewriteДиректива RewriteBase устанавливает конкретный, базовый URL для преобразований в контексте каталога. Как вы увидите ниже, RewriteRule может быть использовано в конфигурационных файлах каталогов (.htaccess). Это будет работать локально, т.е., префикс локального каталога отбрасывается на этом этапе обработки и ваши правила преобразований работают только в оставшейся части. В конце он автоматически добавляется обратно к пути. Настройка по-умолчанию; RewriteBase physical-directory-path
Когда, для какого-нибудь нового URL происходит преобразование, этот модуль должен заново вовлечь этот URL в обработку. Для того чтобы иметь возможность сделать это, нужно знать какие у него префикс или база URL. По-умолчанию этот префикс равен самому пути. Однако на большинстве сайтов URL’ы НЕ прямо соответствуют физическим путям, поэтому это допущение обычно окажется неверным! В этом случае вы должны использовать директиву RewriteBase для указания правильного префикса URL.
Если URL вашего сервера не соответствуют физическим путям к файлам, вы должны использовать RewriteBase в каждом из .htaccess файлов где вы хотите использовать директивы RewriteRule.
Например, предположим следующий конфигурационный файл каталога:
# /abc/def/.htaccess — конфигурационный файл каталога /abc/def # Помните: /abc/def это физический путь /xyz, т.е., у сервера есть # директива ‘Alias /xyz /abc/def’ к примеру RewriteEngine On # даем серверу знать что мы работаем через /xyz а не # через префикс физического пути /abc/def RewriteBase /xyz # теперь правила преобразований RewriteRule ^oldstuff.html$ newstuff.html
В примере выше, запрос к /xyz/oldstuff.html корректно преобразуется в физический файл /abc/def/newstuff.html.
Источник: