Войти через VK Войти через FB Войти через Google Войти через Яндекс
Поиск по сайту
Директива RewriteMap
Описание: | Определяет функцию создания ассоциативного массива для поиска по ключу |
---|---|
Синтаксис: | RewriteMap MapNameMapType:MapSource |
Значение по умолчанию: | нет |
Контекст: | server configvirtual host |
Статус: | Расширение |
Модуль: | mod_rewrite |
Совместимость: | Выбор разных типов dbm доступен в Apache 2.0.41 и более поздних версиях |
Директива RewriteMap ассоциативный массив преобразований, который может быть использован в правилах преобразований и использующий соответствующие функции для вставки/извлечения элементов, для поиска по ключу соответствующих значений. Источник этого поиска может иметь различный тип.
MapName это имя массива которое будет использоваться для поиска соответствующего значения из массива в правиле преобразования через один из следующих конструкторов:
${MapName:LookupKey}
${ MapName:LookupKey|DefaultValue}
Когда встречается подобная конструкция, происходит обращение к массиву 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 www1|www2|www3|www4 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 "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:
Транслирует числовые коды в ключе поиска обратно в специальные символы.
- toupper:
- Внешняя программа преобразования
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
файла с массивом
или пока не произойдет рестарт сервера. Таким образом, вы можете использовать
ассоциативные массивы в правилах которые используются для каждого
запроса. Это не проблема, потому что внешний поиск происходит только один раз!
.
Прокомментировать/Отблагодарить