Ответ 1
В файле htaccess mod_rewrite работает аналогично контейнеру <Directory>
или <Location>
. и RewriteBase
используется для предоставления относительной базы пути.
Например, скажем, что у вас есть эта структура папок:
root
|-- subdir1
|-- subdir2
|-- subsubdir
Итак, вы можете получить доступ:
-
http://example.com/
(root) -
http://example.com/subdir1
(subdir1) -
http://example.com/subdir2
(subdir2) -
http://example.com/subdir2/subsubdir
(subsubdir)
URI, который отправляется через RewriteRule
, относится к каталогу. Поэтому, если у вас есть:
RewriteRule ^(.*)$ -
в корне, а запрос /a/b/c/d
, тогда захваченный URI ($1
) равен a/b/c/d
. Но если правило находится в subdir2
, а запрос /subdir2/e/f/g
, то захваченный URI равен e/f/g
. И если правило находится в subsubdir
, а запрос /subdir2/subsubdir/x/y/z
, то захваченный URI - x/y/z
. Каталог, в котором находится правило, содержит эту часть, удаленную от URI. База rewrite не влияет на это, это просто то, как работает каждый каталог.
Что делает база перезаписи, предоставляет базу URL-пути (а не базу файлов) для любых относительных путей в целевом элементе правила. Поэтому скажите, что у вас есть это правило:
RewriteRule ^foo$ bar.php [L]
bar.php
- относительный путь, а не:
RewriteRule ^foo$ /bar.php [L]
где /bar.php
- абсолютный путь. Абсолютным путем всегда будет "корень" (в структуре каталогов выше). Это означает, что правило находится в "root", "subdir1" , "subsubdir" и т.д. Путь /bar.php
всегда отображается на http://example.com/bar.php
.
Но другое правило, с относительным путем, оно основано на каталоге, в котором находится правило. Поэтому, если
RewriteRule ^foo$ bar.php [L]
находится в "корне", и вы переходите к http://example.com/foo
, вы получаете http://example.com/bar.php
. Но если это правило находится в каталоге "subdir1" , и вы переходите к http://example.com/subdir1/foo
, вам предоставляется http://example.com/subdir1/bar.php
. и т.д. Это иногда работает, а иногда нет, как утверждает документация, оно должно требоваться для относительных путей, но большую часть времени оно, похоже, работает. За исключением случаев, когда вы перенаправляете (используя флаг R
или неявно, потому что у вас есть http://host
в целевом элементе правила). Это означает следующее правило:
RewriteRule ^foo$ bar.php [L,R]
если он находится в каталоге "subdir2", и вы переходите к http://example.com/subdir2/foo
, mod_rewrite будет ошибочно относить путь как путь к файлу вместо URL-пути и из-за флага R
, вы закончите перенаправляется на что-то вроде: http://example.com/var/www/localhost/htdocs/subdir1
. Это, очевидно, не то, что вы хотите.
Здесь находится RewriteBase
. Директива сообщает mod_rewrite, что добавить к началу каждого относительного пути. Поэтому, если у меня есть:
RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]
и это правило находится в "subsubdir", переход на http://example.com/subdir2/subsubdir/foo
будет действительно служить мне http://example.com/blah/bar.php
. "Bar.php" добавляется к концу базы. На практике этот пример обычно не то, что вы хотите, потому что вы не можете иметь несколько оснований в одном контейнере каталога или файле htaccess.
В большинстве случаев он используется следующим образом:
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
где эти правила будут находиться в каталоге "subdir1" и
RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]
будет находиться в каталоге "subsubdir".
Это отчасти позволяет вам сделать ваши правила переносимыми, поэтому вы можете отбросить их в любой каталог и только изменить базу вместо целого ряда правил. Например, если у вас есть:
RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L]
RewriteRule ^blah2$ /subdir1/blah2.php [L]
...
так что переход в http://example.com/subdir1/foo
будет служить http://example.com/subdir1/bar.php
и т.д. И скажите, что вы решили перенести все эти файлы и правила в каталог "subsubdir". Вместо того чтобы менять каждый экземпляр /subdir1/
на /subdir2/subsubdir/
, вы могли иметь только базу:
RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...
И тогда, когда вам нужно было переместить эти файлы и правила в другой каталог, просто измените базу:
RewriteBase /subdir2/subsubdir/
и что он.