RewriteBase
применяется только к мишени о наличии относительного правила перезаписи.
Используя RewriteBase, как это ...
RewriteBase /folder/
RewriteRule a\.html b.html
по сути то же самое, что и ...
RewriteRule a\.html /folder/b.html
Но когда файл .htaccess находится внутри, /folder/
это также указывает на ту же цель:
RewriteRule a\.html b.html
Хотя документы подразумевают всегда использование a RewriteBase
, Apache обычно правильно определяет его для путей в DocumentRoot, если только:
В этих случаях вы можете обнаружить, что вам нужно указать RewriteBase.
Тем не менее, поскольку это непонятная директива, обычно лучше просто указывать абсолютные (иначе называемые «коренные родственники») URI в целях перезаписи. Другие разработчики, читающие ваши правила, поймут это легче.
Цитата из превосходного подробного ответа Джона Линя здесь :
В файле htaccess mod_rewrite работает аналогично контейнеру <Directory>
или <Location>
. и RewriteBase
используется для обеспечения базы относительного пути.
Например, скажем, у вас есть эта структура папок:
DocumentRoot
|-- subdir1
`-- subdir2
`-- subsubdir
Таким образом, вы можете получить доступ к:
http://example.com/
(Корень)
http://example.com/subdir1
(Subdir1)
http://example.com/subdir2
(Subdir2)
http://example.com/subdir2/subsubdir
(Subsubdir)
URI, который отправляется через a, RewriteRule
относится к каталогу, содержащему файл htaccess. Так что если у вас есть:
RewriteRule ^(.*)$ -
- В корне htaccess и запрос есть
/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. База переписывания не влияет на это, это просто, как работает для каждого каталога.
Что делает база перезаписи , так это предоставляет базу 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]
в «субсубдире», собираясь на 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/
и это все.