RewriteBase
jest stosowana tylko do tarczy o względnej reguła przepisywania.
Używanie RewriteBase w ten sposób ...
RewriteBase /folder/
RewriteRule a\.html b.html
jest zasadniczo taki sam jak ...
RewriteRule a\.html /folder/b.html
Ale gdy plik .htaccess znajduje się w środku, oznacza /folder/
to również ten sam cel:
RewriteRule a\.html b.html
Chociaż dokumenty sugerują, że zawsze używa a RewriteBase
, Apache zwykle wykrywa go poprawnie dla ścieżek w DocumentRoot, chyba że:
W takich przypadkach może się okazać, że musisz określić RewriteBase.
Ponieważ jednak jest to myląca dyrektywa, ogólnie lepiej jest po prostu określić bezwzględne (zwane też „względnymi rootami”) identyfikatory URI w obiektach do przepisywania. Inni programiści czytający twoje reguły łatwiej je zrozumieją.
Cytując doskonałą odpowiedź Jona Lin tutaj :
W pliku htaccess mod_rewrite działa podobnie do kontenera <Directory>
lub <Location>
. i RewriteBase
służy do zapewnienia względnej podstawy ścieżki.
Załóżmy na przykład, że masz taką strukturę folderów:
DocumentRoot
|-- subdir1
`-- subdir2
`-- subsubdir
Aby uzyskać dostęp do:
http://example.com/
(korzeń)
http://example.com/subdir1
(subdir1)
http://example.com/subdir2
(subdir2)
http://example.com/subdir2/subsubdir
(subsubdir)
Identyfikator URI wysyłany przez a RewriteRule
jest względny do katalogu zawierającego plik htaccess. Więc jeśli masz:
RewriteRule ^(.*)$ -
- W głównym htaccess, a żądanie jest
/a/b/c/d
, to przechwycony URI ( $1
) jest a/b/c/d
.
- Jeśli reguła jest włączona,
subdir2
a żądanie jest, /subdir2/e/f/g
to przechwycony identyfikator URI to e/f/g
.
- Jeśli reguła znajduje się w
subsubdir
, a żądanie jest /subdir2/subsubdir/x/y/z
, to przechwycony identyfikator URI to x/y/z
.
W katalogu, w którym znajduje się reguła, ta część jest pozbawiona identyfikatora URI. Baza przepisywania nie ma na to wpływu, po prostu działa na katalog.
Co baza przepisać ma zrobić, to stworzyć podstawy ścieżka_url ( nie bazie file-path) dla dowolnego względnych ścieżek w celu reguł można . Powiedzmy, że masz tę zasadę:
RewriteRule ^foo$ bar.php [L]
Jest bar.php
to ścieżka względna, w przeciwieństwie do:
RewriteRule ^foo$ /bar.php [L]
gdzie /bar.php
jest ścieżka absolutna. Ścieżką bezwzględną zawsze będzie „root” (w powyższej strukturze katalogów). Oznacza to, że niezależnie od tego, czy reguła znajduje się w katalogu „root”, „subdir1”, „subsubdir” itd., /bar.php
Ścieżka zawsze jest odwzorowywana http://example.com/bar.php
.
Ale druga reguła, ze ścieżką względną, jest oparta na katalogu, w którym reguła się znajduje. Więc jeśli
RewriteRule ^foo$ bar.php [L]
jest w „katalogu głównym” i idziesz do http://example.com/foo
, dostajesz obsłużony http://example.com/bar.php
. Ale jeśli ta reguła znajduje się w katalogu „subdir1” i przejdziesz do http://example.com/subdir1/foo
, zostaniesz obsłużony http://example.com/subdir1/bar.php
. itp. Czasami to działa, a czasem nie, jak mówi dokumentacja, powinno być wymagane w przypadku ścieżek względnych, ale przez większość czasu wydaje się, że działa. Z wyjątkiem sytuacji, gdy przekierowujesz (używając R
flagi lub pośrednio, ponieważ masz http://host
w celu regułę). Oznacza to, że zasada:
RewriteRule ^foo$ bar.php [L,R]
jeśli jest w katalogu „subdir2” i udać się http://example.com/subdir2/foo
będzie mod_rewrite pomylić ścieżkę względną jako pliku ścieżce zamiast ścieżka_url i ze względu na R
flagi, będziesz skończyć uzyskiwanie przekierowany na coś takiego: http://example.com/var/www/localhost/htdocs/subdir1
. Co oczywiście nie jest tym, czego chcesz.
W tym miejscu RewriteBase
pojawia się. Dyrektywa mówi mod_rewrite, co należy dołączyć na początku każdej ścieżki względnej. Więc jeśli mam:
RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]
w „subsubdir”, http://example.com/subdir2/subsubdir/foo
naprawdę będzie mi służyć http://example.com/blah/bar.php
. „Bar.php” jest dodawany na końcu bazy. W praktyce ten przykład zazwyczaj nie jest tym, czego potrzebujesz, ponieważ nie możesz mieć wielu baz w tym samym kontenerze katalogu lub pliku htaccess.
W większości przypadków jest on używany w następujący sposób:
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
gdzie reguły te znajdują się w katalogu „subdir1” i
RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]
będzie w katalogu „subsubdir”.
To częściowo pozwala uczynić twoje reguły przenośnymi, więc możesz upuścić je w dowolnym katalogu i wystarczy zmienić bazę zamiast kilku reguł. Na przykład, jeśli miałeś:
RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L]
RewriteRule ^blah2$ /subdir1/blah2.php [L]
...
takich, które http://example.com/subdir1/foo
będą służyć http://example.com/subdir1/bar.php
itp. Powiedzmy, że postanowiłeś przenieść wszystkie te pliki i reguły do katalogu „subsubdir”. Zamiast zmieniać każdą instancję /subdir1/
na /subdir2/subsubdir/
, mógłbyś mieć po prostu bazę:
RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...
A kiedy musisz przenieść te pliki i reguły do innego katalogu, po prostu zmień bazę:
RewriteBase /subdir2/subsubdir/
i to wszystko.