Главная страница статей --> Хитрости при программировании php, заметки по базам данных

Модуль Apache mod_rewrite

Источник: realcoding.net

[2 страница]
Эти переменные полностью соответствуют названным похожим образом MIME-заголовкам HTTP , Си переменным сервера Apache или полям struct tm систем Unix. Большинство из них документрованны в других местах руководства или в  спецификации CGI. Те, что являются для mod_rewrite специальными включают:

IS_SUBREQ
Будет содержать текст «true» если запрос выполняется в  текущий момент как подзапрос
, «false» в другом случае. Подзапросы могут быть сгенерированны модулями которым нужно иметь дело с дополнительными файлами или URI для того чтобы выполнить собственные задачи.
API_VERSION
Это версия API модуля Apache
(внутренний интерфейс между сервером и  модулем) в текущей сборке сервера, что определено в  include/ap_mmn.h. API версия модуля соответствует используемой версии Apache (для версии Apache 1.3.14, к примеру это 19990320:10), однако это в основном интересно авторам модулей.
THE_REQUEST
Полная строка HTTP запроса отправленная браузером серверу
(т.е., «GET /index.html HTTP/1.1»). Она не включает какие-либо дополнительные заголовки отправляемые браузером.
REQUEST_URI
Ресурс
, запрошенный в строке HTTP запроса. (В примере выше, это было бы  «/index.html».)
REQUEST_FILENAME
Полный путь в файловой системе сервера к файлу или скрипту соответствующим этому запросу
.

Специальные примечания:

Переменные SCRIPT_FILENAME и REQUEST_FILENAME содержат одинаковые значения, т.е., значение поля filename внутренней структуры request_rec сервера Apache. Первое имя это просто широко известное имя переменной CGI в то время как второе это постоянная копия REQUEST_URI (содержащая значение поля uri структуры request_rec).
Есть специальный формат: %{ENV:переменная} где переменная может быть любой переменной окружения. Это ищется во внутренних структурах Apache и (если там нет) с помощью вызова getenv() из процесса Apache сервера.
Есть специальный формат: %{HTTP:заголовок} где заголовок может быть любым именем HTTP MIME-заголовка. Это ищется в HTTP запросе. Пример: %{HTTP:Proxy-Connection} значение HTTP заголовка «Proxy-Connection:».
Есть специальный формат %{LA-U:переменная} опережающих запросов которые производятся внутренним (основанном на URL) подзапросом для определения конечного значения переменной. Используйте это когда вы хотите использовать переменную для преобразований, которая реально определяется позднее, в какой-либо фазе API, и таким образом недоступна на данном этапе. Для примера когда вы хотите преобразовать соответственно переменной REMOTE_USER из контекста сервера (файл httpd.conf) вы должны использовать %{LA-U:REMOTE_USER} потому что эта переменная устанавливается в фазах авторизации которые идут после фазы трансляции URL в которой и работает mod_rewrite. С другой стороны, по причине реализации работы mod_rewrite в контексте каталога (файл .htaccess) через Fixup фазу API и из-за того, фазы авторизации идут до этой фазы, вы просто можете там использовать %{REMOTE_USER}.
Есть специальный формат: %{LA-F:переменная} который создает внутренний (основанный на имени файла) подзапрос для определения конечного значения переменной. В основном это то же самое что и формат LA-U приведенный выше.
Условие это шаблон условия, т.е., какое-либо регулярное выражение применяемое к текущему экземпляру СравниваемаяСтрока, т.е., СравниваемаяСтрока просматривается на поиск соответствия Условие.

Помните: Условие это perl совместимое регулярное выражение с некоторыми дополнениями:

Вы можете предварять строку шаблона префиксом ! (восклицательный знак) для указания несоответствия шаблону.
Есть некоторые специальные варианты Условиеs. Вместо обычных строк с регулярными выражениями можно также использовать один из следующих вариантов:
<Условие (лексически меньше)
Условие считается простой строкой и лексически сравнивается с СравниваемаяСтрока. Истинно если СравниваемаяСтрока лексически меньше чем Условие.
>Условие (лексически больше)
Условие считается простой строкой и лексически сравнивается с СравниваемаяСтрока. Истинно если СравниваемаяСтрока лексически больше чем Условие.
=Условие (лексически равно)
Условие считается простой строкой и лексически сравнивается с СравниваемаяСтрока. Истинно если СравниваемаяСтрока лексически равно Условие, т.е. эти две строки полностью одинаковы (символ в символ). Если Условие имеет вид "" (два знака дюйма идущих подряд) это сравнивает СравниваемаяСтрока с пустой строкой.
-d (является ли каталогом)
СравниваемаяСтрока считается путем, проверяется существование этого пути и то что этот путь является каталогом.
-f (является ли обычным файлом)
СравниваемаяСтрока считается путем, проверяется существование этого пути и то что этот путь является обычным файлом.
-s (является ли обычным файлом с ненулевым размером)
СравниваемаяСтрока считается путем, проверяется существование этого пути и то что этот путь является обычным файлом, размер которого больше нуля.
-l (является ли символической ссылкой)
СравниваемаяСтрока считается путем, проверяется существование этого пути и то что этот путь является символической ссылкой.
-F (проверка существования файла через подзапрос)
Проверяет через все списки контроля доступа сервера, существующие в настоящий момент, является ли СравниваемаяСтрока существующим файлом, доступным по этому пути. Для этой проверки используется внутренний подзапрос, поэтому используйте эту опцию с осторожностью — это отрицательно сказывается на производительности сервера!
-U (проверка существования URL через подзапрос)
Проверяет через все списки контроля доступа сервера, существующие в настоящий момент, является ли СравниваемаяСтрока существующим URL, доступным по этому пути. Для этой проверки используется внутренний подзапрос, поэтому используйте эту опцию с осторожностью — это отрицательно сказывается на производительности сервера!
Замечание
Все эти проверки также могут быть предварены префиксом восклицательный знак (!) для инвертирования их значения.
Дополнительно вы можете устанавливать специальные флаги для Условие добавляя

[flags]

третьим аргументом в директиву RewriteCond. Flags список следующих флагов разделенных запятыми:

nocaseNC (регистронезависимо)
Регистр не имеет значение, т.е., нет различий между A-Z и a-z как в дополнении СравниваемаяСтрока так и Условие. Этот флаг эффективен только для сравнений между СравниваемаяСтрока и Условие. Он не работает при проверках в файловой системе и в подзапросах.
ornextOR (либо следующее условие)
Используйте для комбинирования условий в правилах OR вместо AND. Типичный пример:

RewriteCond %{REMOTE_HOST}  ^host1.*  [OR]
RewriteCond %{REMOTE_HOST}  ^host2.*  [OR]
RewriteCond %{REMOTE_HOST}  ^host3.*
RewriteRule ...some special stuff for any of these hosts...

Без этого флага вы должны были бы написать это условие/правило три раза.
Пример:

Для выдачи главной страницы какого-либо сайта согласно «User-Agent:» заголовку запроса, вы можете использовать следующие директивы:

RewriteCond  %{HTTP_USER_AGENT}  ^Mozilla.*
RewriteRule  ^/$                 /homepage.max.html  [L]

RewriteCond  %{HTTP_USER_AGENT}  ^Lynx.*
RewriteRule  ^/$                 /homepage.min.html  [L]

RewriteRule  ^/$                 /homepage.std.html  [L]

Интерпретация: Если у вас Netscape Navigator (который идентифицируется как Mozilla), вы выдаете максимально навороченную страницу, с фреймами, и т.д. Если у вас Lynx (текстовый браузер), вы выдаете наименее навороченную страницу, без рисунков, таблиц и т.д. Если любой другой браузер, выдаете стандартную страницу.

RewriteEngine Директива


Описание: Включает или выключает работу механизма преобразования
Синтаксис: RewriteEngine onoff
Значение по умолчанию: RewriteEngine off
Контекст: server configvirtual hostdirectory.htaccess
Разрешение: FileInfo
Статус: Расширение
Модуль: mod_rewrite

Директива RewriteEngine включает или выключает работу механизма преобразований. Если она установлена в положение off этот модуль совсем не работает. Он даже не обновляет переменные окружения SCRIPT_URx.

Используйте эту директиву для выключения этого модуля вместо простого закомментирования директив RewriteRule!

Отметьте, что по-умолчанию, настройки преобразований не наследуются. Это означает что вы должны иметь RewriteEngine on директиву для каждого виртуального хоста в котором вы хотите использовать этот модуль.

RewriteLock Директива


Описание: Устанавливает имя файла используемого для RewriteMap синхронизации
Синтаксис: RewriteLock file-path
Значение по умолчанию: None
Контекст: server config
Статус: Расширение
Модуль: mod_rewrite

Эта директива определяет имя файла синхронизации который нужен mod_rewrite для связи с RewriteMap программами. Сделайте этот файл локальным (размещенным не на NFS-смонтированном ресурсе) когда вы хотите использовать программу для создания ассоциативного массива преобразований. Это не является обязательным для других типов таких массивов.

RewriteLog Директива


Описание: Устанавливает имя файла используемое для ведения журнала механизма преобразования
Синтаксис: RewriteLog file-path
Контекст: server configvirtual host
Статус: Расширение
Модуль: mod_rewrite

Директива RewriteLog устанавливает имя файла а котором сервер ведет журнал любых происходящих действий по преобразованиям URL. Если это имя не начинается со слэша (/) в этом случае путь считается от Server Root. В конфигурационном файле сервера эта директива должна встерчаться только один раз.

Для отключения ведения журнала преобразований не рекомендуется устанавливать Filename в /dev/null, потому что хотя механизм преобразований и не производит вывод в файл журнала в этом случае, внутри он все ещё ведет журнализацию. Это замедлит сервер без каких-либо преимуществ для администратора! Для отключения ведения журнала либо удалите либо закомментируйте директиву RewriteLog либо используйте RewriteLogLevel 0!

Безопасность


Смотрите документ Apache Security Tips для более подробной информации о том почему вы можете быть уязвимы если в каталоги где хранятся файлы журналов разрешена запись кому угодно кроме пользователя от имени которого запускается сервер.

RewriteLog /usr/local/var/apache/logs/rewrite.log

RewriteLogLevel Директива


Описание: Устанавливает уровень детализации при журнализации действий механизма преобразований
Синтаксис: RewriteLogLevel Level
Значение по умолчанию: RewriteLogLevel 0
Контекст: server configvirtual host
Статус: Расширение
Модуль: mod_rewrite

Директива RewriteLogLevel устанавливает уровень детализации журнала механизма преобразований. По-умолчанию уровень 0 означающий что журнализация не ведется, в то время как 9 или более означает что записываются практически все действия.

Для отключения журнализации действий механизма преобразований просто установите уровень на 0. Это отключает ведение журнала для всех действий по преобразованиям.

Использование больших значений уровня очень сильно замедлит ваш сервер Apache! Используйте журнал преобразований на уровне большем чем 2 только для отладочных целей!

RewriteLogLevel 3

RewriteMap Директива


Описание: Определяет функцию создания ассоциативного массива для поиска по ключу
Синтаксис: RewriteMap MapNameMapType:MapSource
Значение по умолчанию: нет
Контекст: server configvirtual host
Статус: Расширение
Модуль: mod_rewrite
Совместимость: Выбор разных типов dbm доступен в Apache 2.0.41 и более поздних версиях

Директива RewriteMap ассоциативный массив преобразований, который может быть использован в правилах преобразований и использующий соответствующие функции для вставки/извлечения элементов, для поиска по ключу соответствующих значений. Источник этого поиска может иметь различный тип.

MapName это имя массива которое будет использоваться для поиска соответствующего значения из массива в правиле преобразования через один из следующих конструкторов:

${MapName:LookupKey}
${MapName:LookupKeyDefaultValue}

Когда встречается подобная конструкция, происходит обращение к массиву MapName и поиск значения сопоставленного ключу LookupKey. Если найдено искомое значение ключа, происходит извлечение значения SubstValue с помощью соответствующей функции. Если ключ не найден тогда происходит подстановка DefaultValue или пустой строки если не указана DefaultValue.

Могут быть использованы следующие комбинации типа функции — MapType для вставки/извлечения элементов массива и MapSource — самого ассоциативного массива:

Простой текст
MapType: txt, MapSource: Путь к существующему файлу в файловой системе Unix
Это стандартная опция для создания ассоциативного массива где MapSource это простой текстовый ASCII файл содержащий либо пустый строчки, строчки комментариев (начинающиеся с символа #) либо пары подобные следующим — одна в строчке:

MatchingKeySubstValue

Пример
##
##  map.txt -- массив преобразований
##

Ralf.S.Engelschall    rse   # Bastard Operator From Hell
Mr.Joe.Average        joe   # Mr. Average
RewriteMap real-to-user txt:/path/to/file/map.txt

Произвольный простой текст
MapType: rnd, MapSource: Путь к существующему файлу в файловой системе Unix
Этот вариант идентичен варианту с простым текстом приведённом выше но со специальной особенностью пост-обработки: После нахождения какую-либо величину производится её анализ на предмет нахождения символов «» которые имеют значение логического «или». Другими словами они означают набор альтернативных вариантов и выбор возвращаемой величины из них производится произвольно. Хотя это кажется безумием и абсолютно бесполезным, это в действительности используется для балансировки нагрузки в ситуациях с обратным прокси где происходит поиск имен серверов. Например:

##
##  map.txt -- массив преобразований
##

static   www1www2www3www4
dynamic  www5
www6
RewriteMap servers rnd
:/path/to/file/map.txt

Хэш файл
MapType: dbm[=type], MapSource: Путь к существующему файлу в файловой системе Unix
Здесь, источник — это двоичный файл DBM формата содержащий то же самое содержимое что и простой текстовый файл, однако в специальном виде, оптимизированном для действительно быстрого поиска. Этот тип может быть sdbm, gdbm, ndbm, или db в зависимости от настроек при компиляции. Если тип опущен, выбирается тип установленный по-умолчанию при компиляции. Вы можете создавать такой файл любой утилитой DBM или следующим Perl скриптом. Убедитесь что он настроен для создания требуемого типа DBM файла. Этот пример создает файл NDBM.

#!/path/to/bin/perl
##
##  txt2dbm -- convert txt map to dbm format
##

use NDBM_File;
use
Fcntl;

(
$txtmap, $dbmmap) = @ARGV;

open(TXT, <$txtmap) or die Couldnt open $txtmap!n;
tie (%DB, NDBM_File, $dbmmap,O_RDWRO_TRUNCO_CREAT, 0644)
  or die
Couldnt create $dbmmap!n;

while (<
TXT>) {
 
next if (/^s*#/ or /^s*$/);
 
$DB{$1} = $2 if (/^s*(S+)s+(S+)/);
}

untie %DB;
close(TXT);
$
txt2dbm map.txt map.db

Внутренняя функция
MapType: int, MapSource: внутренняя функция Apache
Здесь, источник — это какая-либо внутренняя функция Apache. В настоящее время вы не можете создавать свои собственные функции, однако уже существуют следующие функции:

toupper:
Преобразует ключ поиска в верхний регистр.
tolower:
Преобразует ключ поиска в нижний регистр.
escape:
Транслирует специальные символы в ключе поиска в их числовые коды.
unescape:
Транслирует числовые коды в ключе поиска обратно в специальные символы.
Внешняя программа преобразования
MapType: prg, MapSource: Путь к существующему файлу в файловой системе Unix
Здесь, источник — это программа, а не файл с ассоциативным массивом. Для её создания вы можете использовать любой выбранный язык, однако результат должен быть исполняемым файлом (т.е., либо объектным кодом либо скриптом с магической первой строчкой #!/path/to/interpreter).

Эта программа запускается один раз при запуске сервера Apache и затем взаимодействует с механизмом преобразований через файловые обработчики stdin(поток ввода) и stdout(поток вывода). Для каждого поиска в массиве, соответствующий ключ для поиска, будет получаться в виде строки, подаваемой на stdin и оканчивающейся символом перевода строки. Затем эта программа должна вернуть значение найденной величины в stdout в виде строки оканчивающейся символом перевода строки либо строкой из четырёх символов «NULL» если поиск неудачен (т.е., для соответствующего значения ключа не найдено никакого значения). Тривиальная программа реализующая массив 1:1 (т.е., ключ == значение) может выглядеть так:

#!/usr/bin/perl
$ = 1;
while (<
STDIN>) {
   
# ...put here any transformations or lookups...
   
print $_;
}

Однако будьте очень осторожны:

"Keep it simple, stupid" (KISS) — делай это проще, дурачок, потому что если эта программа зависнет — это повесит сервер Apache когда встретится правило использующее этот массив (создаваемый внешней программой).
Для избежания распространенной ошибки: никогда не делайте буферизованный ввод/вывод для stdout! Это вызовет бесконечное зацикливание! Отсюда «$=1» в вышеприведенном примере…
Используйте директиву RewriteLock для определения файла блокировок который mod_rewrite может использовать для синхронизации связи с этой программой. По-умолчанию такая синхронизация не производится.
Директива RewriteMap может встречаться более одного раза. Для каждого массива используйте одну RewriteMap директиву для объявления файла с массивом преобразований. В то время как вы не можете определять массив в контексте каталога, его использование в этом контексте конечно же возможно.

Замечание
Для простого текстового и DBM файлов ключи поиска кэшируются ядром до тех пор пока не изменится тип mtime файла с массивом или пока не произойдет рестарт сервера
. Таким образом, вы можете использовать ассоциативные массивы в правилах которые используются для каждого запроса. Это не проблема, потому что внешний поиск происходит только один раз!

RewriteOptions Директива


Описание: Устанавливает кое-какие специальные опции для механизма преобразований
Синтаксис: RewriteOptions Options
Значение по умолчанию: None
Контекст: server configvirtual hostdirectory.htaccess
Разрешение: FileInfo
Статус: Расширение
Модуль: mod_rewrite

Директива RewriteOptions устанавливает некоторые специальные опции для текущей конфигурации в контексте сервера или каталога. Строки Option могут иметь следующий вид:

inherit
Это приводит в действие наследование текущей конфигурацией конфигурации родителя. В контексте виртуального сервера это означает что ассоциативные массивы, условия и правила основного сервера наследуются. В контексте каталога это означает что условия и правила в конфигурационных файлах .htaccess родительских каталогов наследуются.

RewriteRule Директива


Описание: Определяет правила для механизма преобразований
Синтаксис: RewriteRule ШаблонПодстановка
Значение по умолчанию: None
Контекст: server configvirtual hostdirectory.htaccess
Разрешение: FileInfo
Статус: Расширение
Модуль: mod_rewrite
Совместимость: Флаг cookie доступен в Apache 2.0.40 и более поздних.

Директива 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 ("perldoc perlre"). Если вы заинтересованы в ещё более детальной информации о регулярных выражениях и их диалектах (POSIX и т.д.), смотрите следующую, специально написанную по этой теме книгу:

Mastering Regular Expressions
Jeffrey E.F. Friedl
Nutshell Handbook Series
OReilly & Associates, Inc. 1997
ISBN 1-56592-257-3


Кроме того, в mod_rewrite символ отрицания (NOT) (!) — допускаемый префикс в шаблоне. Это даёт вам возможность инвертировать действие шаблона; ну к примеру скажем: "если текущий URLне совпадает с этим шаблоном". Это может быть использовано в особых случаях, когда проще найти шаблон для несоответствия, или в качестве последнего правила, работающего по умолчанию.

Примечание
При использовании символа NOT (не) для инвертирования действия шаблона вы не можете иметь сгруппированные части групповых символов в шаблоне. Это невозможно потому что когда нет соответствия шаблону, для групп нет никакого содержимого. В результате, если используются шаблоны с отрицанием, вы не можете использовать $N в строках подстановок!
Подстановка в правиле преобразования это строка будет подставляться (или будет заменять) вместо оригинального URL, для которого естьсовпадение Шаблону. Кроме простого текста вы можете использовать

обратные связи $N на шаблоны в RewriteRule
обратные связи %N на последний соответствующий шаблон в RewriteCond
переменные сервера в качестве проверяемых строк в условиях правил (%{VARNAME})
вызовы запросов к массиву (${mapname:keydefault})
Обратные связи это $N (N=0..9) идентификаторы которые заменяются содержимым N-й группы подходящего Шаблона. Переменные сервера Это тоже самое что и СравниваемаяСтрока директивы RewriteCond. Запросы к массиву пришли из директивы RewriteMap там они и объяснены. Эти три типа переменных рассматриваются в порядке, в котором они идут в вышеприведенном списке.

Как уже было упомянуто выше, все правила преобразований применяются с использованием Подстановки (в порядке, в котором они определены в конфигурационном файле). URL полностью заменяется Подстановкой и процесс преобразования идет до тех пор, пока не останется больше никаких правил, если только он не прерван специально, с помощью флага L — см. ниже.

Существует специальная строка подстановки вида - которая означает: НЕТ подстановки! Звучит глупо? Нет, это полезно для правил преобразования которые только проверяют некоторые URL однако не производят подстановок, т.е., в связке с флагом C (цепочка) возможно иметь более чем один шаблон, применяемый перед проведением непосредственно самой подстановки.

Ещё одно замечание: Вы даже можете создавать URL, содержащие строку запроса, в строке подстановки. Просто используйте вопросительный знак внутри строки подстановки для указания того, следующее за ним содержимое должно быть преобразовано в QUERY_STRING (строку запроса). Когда вы хотите убрать существующую строку запроса, завершайте строку подстановки просто вопросительным знаком.

Примечание
Есть одна особенность: Когда вы предваряете поле подстановки строкой http://thishost[:thisport], — mod_rewrite отрезает её автоматически. Это автоматическое усечение подразумеваемое при внешнем редиректе URL полезная и важная особенность при использовании в связке с запросами к массивам преобразований генерирующих имя хоста. Взгляните на первый пример, в разделе примеров ниже, чтобы понять это.
Помните
Безусловный внешний редирект на ваш собственный сервер не будет работать с префиксом http://thishost из-за этой особенности. Чтобы использовать такой саморедирект, Вы должны использовать флаг R(см. ниже).
В подстановке вы можете использовать, в том числе, и специальные флаги путем добавления следующей конструкции:



Похожие статьи:
- Установка и конфигурация веб сервера Apache с поддержкой PHP, JSP и MySQL на Windows XP
- Парсинг на Perl
- Perl & XML. Библиотека программиста
- Генерация контента сайта с использованием Template Toolkit
- Использование модуля для работы с шаблонами. Часть 2.
- Модуль Apache mod_rewrite
- Модуль Apache mod_rewrite
- Включите графику!!!
- Фильтры DHTML
- Поиск по сайту - статичный контент (Perl)
- Как подружить интерпретатор Perl с Homesite
- Работа с MS Access в PHP
- История языка HTML


Оглавление | Обсудить на форуме | Главная страница сайта | Карта сайта |

Контакты
Редакция:
[0.001]