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
(sububdir)
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]
в "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/
і це все.