Определяет функцию создания ассоциативного массива для поиска по ключу
Синтаксис:
RewriteMap MapNameMapType:MapSource
Значение по умолчанию:
нет
Контекст:
server configvirtual host
Статус:
Расширение
Модуль:
mod_rewrite
Совместимость:
Выбор разных типов dbm доступен в Apache 2.0.41 и более поздних версиях
Директива RewriteMapассоциативный массив преобразований, который может быть использован в правилах преобразований и использующий соответствующие функции для вставки/извлечения элементов, для поиска по ключу соответствующих значений. Источник этого поиска может иметь различный тип.
MapName это имя массива которое будет использоваться для поиска соответствующего значения из массива в правиле преобразования через один из следующих конструкторов:
Когда встречается подобная конструкция, происходит обращение к массиву 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
Этот вариант идентичен варианту с простым текстом приведённом выше но со специальной особенностью пост-обработки: После нахождения какую-либо величину производится её анализ на предмет нахождения символов «|» которые имеют значение логического «или». Другими словами они означают набор альтернативных вариантов и выбор возвращаемой величины из них производится произвольно. Хотя это кажется безумием и абсолютно бесполезным, это в действительности используется для балансировки нагрузки в ситуациях с обратным прокси где происходит поиск имен серверов. Например:
Хэш файл 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 "Couldn't open $txtmap!\n";
tie (%DB, 'NDBM_File', $dbmmap,O_RDWR|O_TRUNC|O_CREAT, 0644)
or die "Couldn't 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 файла с массивом или пока не произойдет рестарт сервера. Таким образом, вы можете использовать ассоциативные массивы в правилах которые используются для каждого запроса. Это не проблема, потому что внешний поиск происходит только один раз!