Внутренние процессы в этом модуле очень сложны, однако, их нужно объяснить хотя бы раз, и даже обычному пользователю, во избежание распространённых ошибок и раскрытия всей его функциональности.
Фазы API
Для начала, нужно просто понять, что обработку какого-либо HTTP запроса, сервер Apache делает в фазах. Перехватчик этих фаз обеспечивается Apache API. Mod_rewrite использует 2 из этих перехватчиков: транслятор из URL в имя файла используемый после считывания HTTP запроса, но до начала какой-либо авторизации и перехватчик адресной привязки начинающий работать после фаз авторизации и считывания конфигурационных файлов каталога (.htaccess), но до активизации обработчика содержания.
Поэтому, после поступления запроса и определения Apache'ем соответствующего сервера (или виртуального сервера) механизм преобразований начинает обработку всех директив mod_rewrite из конфигурационного файла сервера в фазе трансляции из URL в имя файла. Несколько шагов спустя, когда находятся каталоги с конечными данными, конфигурационные директивы mod_rewrite запускаются в фазе адресной привязки. В обоих этих ситуациях mod_rewrite преобразует URL, либо в новые URL, либо в имена файлов, хотя между ними нет объективных различий. При создании API, не предполагалось его использование таким образом, однако что касается Apache 1.x это единственный возможный способ работы mod_rewrite. Чтобы внести больше ясности запомните 2 вещи:
Хотя mod_rewrite и преобразует URL в URL, URL в имена файлов и даже имена файлов в имена файлов, в настоящий момент API предоставляет только перехватчик для преобразования URL в имя файла. Во 2-м Apache будут добавлены 2 отсутствующих перехватчика для того, чтобы сделать этот процесс более логичным. Однако это никак не влияет на пользователя, — просто этот факт надо запомнить: Apache в перехватчике URL имя файла делает больше нежели чем это подразумевается в API.
Бесподобный mod_rewrite проделывает URL преобразования и в контексте каталога, т.е. в файлах .htaccess, хотя они и обрабатываются намного позже трансляции URL в имена файлов. Так должно быть, потому что .htaccess файлы находятся в файловой системе, и поэтому обработка уже дошла до этой стадии. Другими словами: Согласно фазам API, — в это время уже слишком поздно управлять URL. Чтобы решить проблему курицы и яйца, mod_rewrite использует хитрость: когда вы манипулируете URL/именем файла в контексте каталога, mod_rewrite сначала преобразует имя файла обратно, к соответствующему ему URL (что обычно невозможно, однако, смотрите директиву RewriteBase чуть ниже, где написано как это сделать) и затем инициирует новый внутренний подзапрос с этим новым URL. Это перезапускает процесс обработки фаз API.
И снова mod_rewrite упорно пытается сделать этот сложный шаг полностью прозрачным для пользователя, однако здесь вам следует запомнить: в то время как манипуляции с URL контексте сервера действительно быстры и эффективны, манипуляции в контексте каталога медленны и неэффективны из-за проблемы курицы и яйца. Однако, с другой стороны это единственный возможный путь работы mod_rewrite (локально ограниченный) для URL преобразований, доступный обычному пользователю.
Не забывайте 2 эти вещи!
Обработка наборов правил
Запускаясь в этих двух фазах API, mod_rewrite считывает конфигурационные наборы правил из своей конфигурационной структуры (создаваемой либо один раз при запуске сервера, — для контекста сервера, либо каждый раз при обходе ядром Apache каталогов, — для контекста каталога). Затем запускается механизм URL преобразований с уже имеющимся набором правил (правило(а) вместе со своими условиями). Функционирование самого механизма преобразований в точности одинаково для обоих контекстов конфигурации. Различаются только конечные результы обработки.
Порядок правил в наборе важен потому что механизм преобразований обрабатывает их в специальном (и не очень очевидном) порядке. Вот это правило: Механизм преобразований просматривает весь набор правил строчка за строчкой (RewriteRule директивы) и когда находится соответствие конкретному правилу производится просмотр соответствующих этому правилу условий (RewriteCond директивы). По историческим причинам условия находятся перед правилами, и поэтому последовательность выполнения команд немного более длинная. См. рис. 1 для более подробной информации.
Рисунок 1: Последовательность выполнения комад при обработке набора правил
Как вы можете видеть, сначала URL сравнивается с Шаблон для каждого из правил. При неудаче mod_rewrite сразу же останавливает обработку этого правила и продолжает работу, используя следующее правило. Если Шаблон совпадает, mod_rewrite ищет соответствующие этому правилу условия. Если их нет, он просто заменяет URL новой величиной полученной из строки Подстановка и продолжает дальше обрабатывать правила. Однако если существуют условия, запускается внутренний цикл для их обработки в том порядке в котором они перечислены. Для условий эта логика другая: мы не сравниваем URL на соответствие какому-либо шаблону. Вместо этого мы сначала создаем строку СравниваемаяСтрока дополняя её переменными, обратными ссылками, запросами в базы данных, и т.д. и затем пытаемся проверять на соответствие с Условие. Если шаблон не соответствует, весь набор условий и соответствующих правил считается несоответствующим условию. Если есть соответствие шаблону, в этом случае производится обработка следующего условия до тех пор пока они будут не исчерпаны. Если все условия совпадают, процесс обработки продолжается с использованием для URL подстановки данных из поля Подстановка.
Экранирование специальных символов
Что касается Apache 1.3.20, специальные символы в СравниваемаяСтрока и Подстановка строках могут быть экранированы (имеется ввиду, отношение к ним как к нормальным символам без их обычного специального значения) путем предшествующего им символа слеша ('\'). Другими словами, вы можете включать символ доллара в строку Подстановка используя '\$'; это не позволит mod_rewrite относиться к нему как к обратной ссылке.
Наличие обратных связей в регулярных выражениях
Здесь нужно запомнить одну важную вещь: Всякий раз, когда вы используете круглые скобки в Шаблон или в одном из Условие, создаются внутренние обратные связи которые могут быть использованы со строками $N и %N (см. ниже). Они полезны при создании строк Подстановка и СравниваемаяСтрока. Рисунок 2 показывает в какие места при дополнении (строк Подстановка и СравниваемаяСтрока) перемещаются обратные связи.
Рисунок 2: Движение обратных связей в правиле.
Итак, — это был неподъёмный курс по внутренним механизмам mod_rewrite, но он вам сильно поможет при дальнейшем чтении документации по данному модулю.