Директива RewriteBase используется mod_rewrite исключительно на этапах перенаправления и игнорируется при любой другой обработке.Вопреки тому, что говорится в документации, это часто не нужно, поскольку (как и в вашем случае) довольно часто URL-адрес сопоставляется с подкаталогами в файловой системе за пределами DOCUMENT_ROOT
.
Итак, что делаетдиректива делать?Когда ваши правила оцениваются в контексте каждого каталога, как это делается при использовании файла .htaccess, URL передается mod_rewrite очень поздно в цепочке обработки запросов Apache.Это означает, что URL-адрес, возможно, уже был частично переведен в путь файловой системы, поэтому путь в / directory / subdirectory / file мог фактически быть доступен через веб-сервер через / location / subdirectory/file.
Это не кажется большой проблемой, но тот факт, что кусок / location / был потерян, создает проблему для mod_rewrite.Чтобы понять почему, вы должны знать, как mod_rewrite делает возможным перезапись контекста для каждого каталога.
Когда вы выполняете перезапись в файле .htaccess, mod_rewrite повторно вводит измененный запрос в Apache как внутренний редирект, как если бы онбыл URL.Это проблематично, поскольку путь запроса может не соответствовать URL для передачи.Например, если запрос оказался в / directory / subdirectory / file (который, как мы предполагаем, находится за пределами DOCUMENT_ROOT
), у нас может быть это правило в / directory / .htaccess :
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php
При этом будет проверен / подкаталог / файл , решено, что это не фактический файл, и переписан его в index.php .В этот момент новый URL должен быть возвращен Apache для внутреннего перенаправления, чтобы завершить перезапись.Поскольку он не имеет контрольной точки, он в конечном итоге отправляет весь путь, то есть отправляет / directory / index.php .Это не то, что вам нужно, так как URL для доступа к этому местоположению на самом деле будет / location / index.php .Вот тут и приходит RewriteBase. Если указать
RewriteBase /location/
в файле .htaccess, префикс каталога / directory / будет заменен на / location / какчасть этой обработки после перезаписи, приводящая к внутреннему перенаправлению на ожидаемый URL / location / index.php .
Это также имеет значение для внешних перенаправлений.Если вы попытаетесь перенаправить извне, используя флаг [R]
, указав только путь, и путь не будет иметь прямой косой черты, весь каталог будет отправлен обратно клиенту способом, описанным выше, если только он не будет заменен значениемдано в RewriteBase.
Ни одна из этих точек не представляется релевантной вашей ситуации, поэтому вам следует подойти без указания RewriteBase.
Переменная %{DOCUMENT_ROOT}
является только значением внутренней ApacheDOCUMENT_ROOT
переменная, которая устанавливается в конфигурации вашего сервера / виртуального хоста.Он всегда соответствует каталогу, в который разрешается запрос к / .Для проверок -f
и -d
требуется полный путь к файловой системе, поэтому %{DOCUMENT_ROOT}
необходимо использовать предварительный путь к относительному пути при их использовании.
Для разрешения пути текущего запроса, однако, mod_rewriteпозаботится об этом с помощью переменной %{REQUEST_FILENAME}
.Например, предполагая, что файл .htaccess находится в вашем подкаталоге / secure , вы можете изменить свой набор правил следующим образом:
RewriteEngine On
# Force PHP extension if not a directory
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^.*$ $0.php [L]