RewriteBase
é aplicado apenas ao destino de uma regra de reescrita relativa .
Usando RewriteBase como este ...
RewriteBase /folder/
RewriteRule a\.html b.html
é essencialmente o mesmo que ...
RewriteRule a\.html /folder/b.html
Mas quando o arquivo .htaccess está dentro /folder/
, isso também aponta para o mesmo destino:
RewriteRule a\.html b.html
Embora os documentos impliquem sempre o uso de a RewriteBase
, o Apache geralmente o detecta corretamente para caminhos no DocumentRoot, a menos que:
Nesses casos, você pode achar que precisa especificar o RewriteBase.
No entanto, como é uma diretiva confusa, geralmente é melhor especificar simplesmente URIs absolutos (também conhecidos como "root-root") em seus destinos de reescrita. Outros desenvolvedores que leem suas regras as entenderão mais facilmente.
Citando a excelente resposta detalhada de Jon Lin aqui :
Em um arquivo htaccess, mod_rewrite funciona de maneira semelhante a um <Directory>
ou <Location>
container. e o RewriteBase
é usado para fornecer uma base de caminho relativa.
Por exemplo, digamos que você tenha esta estrutura de pastas:
DocumentRoot
|-- subdir1
`-- subdir2
`-- subsubdir
Então você pode acessar:
http://example.com/
(raiz)
http://example.com/subdir1
(subdir1)
http://example.com/subdir2
(subdir2)
http://example.com/subdir2/subsubdir
(subsubdir)
O URI que é enviado por meio de RewriteRule
é relativo ao diretório que contém o arquivo htaccess. Então, se você tem:
RewriteRule ^(.*)$ -
- No htaccess raiz, e a solicitação é
/a/b/c/d
, então o URI ( $1
) capturado é a/b/c/d
.
- Se a regra estiver dentro
subdir2
e a solicitação estiver /subdir2/e/f/g
, o URI capturado estará e/f/g
.
- Se a regra estiver no
subsubdir
e a solicitação estiver /subdir2/subsubdir/x/y/z
, o URI capturado estará x/y/z
.
O diretório em que a regra está possui essa parte removida do URI. A base de reescrita não afeta isso; é assim que funciona por diretório.
O que a base de reescrita faz é fornecer uma base de caminho de URL ( não uma base de caminho de arquivo) para quaisquer caminhos relativos no destino da regra . Então diga que você tem esta regra:
RewriteRule ^foo$ bar.php [L]
O bar.php
caminho é relativo, em oposição a:
RewriteRule ^foo$ /bar.php [L]
onde o /bar.php
é um caminho absoluto. O caminho absoluto será sempre a "raiz" (na estrutura de diretórios acima). Isso significa que, independentemente de a regra estar na "raiz", "subdir1", "subsubdir" etc.), o /bar.php
caminho sempre é mapeado para http://example.com/bar.php
.
Mas a outra regra, com o caminho relativo, é baseada no diretório em que a regra está. Portanto, se
RewriteRule ^foo$ bar.php [L]
está na "raiz" e você acessa http://example.com/foo
, é servido http://example.com/bar.php
. Mas se essa regra estiver no diretório "subdir1" e você for http://example.com/subdir1/foo
, será atendido http://example.com/subdir1/bar.php
. etc. Isso às vezes funciona e às vezes não, como diz a documentação, é necessário para caminhos relativos, mas na maioria das vezes parece funcionar. Exceto quando você está redirecionando (usando a R
bandeira ou implicitamente porque você tem http://host
no destino da sua regra). Isso significa esta regra:
RewriteRule ^foo$ bar.php [L,R]
se é no diretório "subdir2", e você vai para http://example.com/subdir2/foo
, mod_rewrite vai confundir o caminho relativo como um arquivo-caminho em vez de um URL-path e por causa da R
bandeira, você vai acabar sendo redirecionado para algo como: http://example.com/var/www/localhost/htdocs/subdir1
. O que obviamente não é o que você deseja.
É aqui que RewriteBase
entra. A diretiva diz ao mod_rewrite o que acrescentar ao início de cada caminho relativo. Então, se eu tiver:
RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]
em "subsubdir", vou http://example.com/subdir2/subsubdir/foo
realmente me servir http://example.com/blah/bar.php
. O "bar.php" é adicionado ao final da base. Na prática, este exemplo geralmente não é o que você deseja, porque você não pode ter várias bases no mesmo contêiner de diretório ou arquivo htaccess.
Na maioria dos casos, é usado assim:
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
onde essas regras estariam no diretório "subdir1" e
RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]
estaria no diretório "subsubdir".
Em parte, isso permite que você torne suas regras portáteis, para que você possa descartá-las em qualquer diretório e precisar alterar apenas a base, em vez de várias regras. Por exemplo, se você tivesse:
RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L]
RewriteRule ^blah2$ /subdir1/blah2.php [L]
...
tal que vai http://example.com/subdir1/foo
servir http://example.com/subdir1/bar.php
etc. E diga que você decidiu mover todos esses arquivos e regras para o diretório "subsubdir". Em vez de alterar todas as instâncias de /subdir1/
para /subdir2/subsubdir/
, você poderia ter apenas uma base:
RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...
E então, quando você precisava mover esses arquivos e as regras para outro diretório, basta alterar a base:
RewriteBase /subdir2/subsubdir/
e é isso.