RewriteBase
n'est appliqué qu'à la cible d'une règle de réécriture relative .
Utiliser RewriteBase comme ceci ...
RewriteBase /folder/
RewriteRule a\.html b.html
est essentiellement le même que ...
RewriteRule a\.html /folder/b.html
Mais lorsque le fichier .htaccess est à l'intérieur, /folder/
cela pointe également vers la même cible:
RewriteRule a\.html b.html
Bien que les documents impliquent toujours d'utiliser un RewriteBase
, Apache le détecte généralement correctement pour les chemins sous DocumentRoot, sauf si:
Dans ces cas, vous pouvez constater que vous devez spécifier la RewriteBase.
Cependant, comme il s'agit d'une directive déroutante, il est généralement préférable de simplement spécifier des URI absolus (aka 'root relative') dans vos cibles de réécriture. Les autres développeurs lisant vos règles les comprendront plus facilement.
Citant ici l'excellente réponse détaillée de Jon Lin :
Dans un fichier htaccess, mod_rewrite fonctionne comme un <Directory>
ou<Location>
conteneur. et le RewriteBase
est utilisé pour fournir une base de chemin relatif.
Par exemple, supposons que vous ayez cette structure de dossiers:
DocumentRoot
|-- subdir1
`-- subdir2
`-- subsubdir
Vous pouvez donc accéder à:
http://example.com/
(racine)
http://example.com/subdir1
(subdir1)
http://example.com/subdir2
(subdir2)
http://example.com/subdir2/subsubdir
(subsubdir)
L'URI qui est envoyé via un RewriteRule
est relatif au répertoire contenant le fichier htaccess. Donc si vous avez:
RewriteRule ^(.*)$ -
- Dans le htaccess racine, et la demande est
/a/b/c/d
, puis l'URI capturé ($1
) est a/b/c/d
.
- Si la règle est en place
subdir2
et que la demande est/subdir2/e/f/g
l'URI capturé l'est e/f/g
.
- Si la règle se trouve dans le
subsubdir
, et que la demande l'est /subdir2/subsubdir/x/y/z
, l'URI capturé l'est x/y/z
.
Le répertoire dans lequel se trouve la règle a cette partie supprimée de l'URI. La base de réécriture n'a aucun effet sur cela, c'est simplement comment fonctionne le répertoire.
Qu'est - ce que la base de réécriture ne fait, est de fournir une base chemin URL ( pas pour tous les chemins relatifs à la base-chemin du fichier) cible de règle . Alors disons que vous avez cette règle:
RewriteRule ^foo$ bar.php [L]
Le bar.php
est un chemin relatif, par opposition à:
RewriteRule ^foo$ /bar.php [L]
où le /bar.php
est un chemin absolu. Le chemin absolu sera toujours la "racine" (dans la structure de répertoires ci-dessus). Cela signifie que, indépendamment du fait que la règle se trouve dans la "racine", "subdir1", "subsubdir", etc., le /bar.php
chemin correspond toujours àhttp://example.com/bar.php
.
Mais l'autre règle, avec le chemin relatif, elle est basée sur le répertoire dans lequel se trouve la règle. Donc, si
RewriteRule ^foo$ bar.php [L]
est dans la "racine" et vous allez http://example.com/foo
, vous êtes servi http://example.com/bar.php
. Mais si cette règle se trouve dans le répertoire "subdir1" et que vous y accédez http://example.com/subdir1/foo
, vous êtes servi http://example.com/subdir1/bar.php
. etc. Cela fonctionne parfois et parfois non, comme le dit la documentation, il est censé être requis pour les chemins relatifs, mais la plupart du temps cela semble fonctionner. Sauf lorsque vous redirigez (en utilisant l' R
indicateur, ou implicitement parce que vous avez http://host
dans la cible de votre règle). Cela signifie que cette règle:
RewriteRule ^foo$ bar.php [L,R]
s'il se trouve dans le répertoire "subdir2" et que vous y accédez http://example.com/subdir2/foo
, mod_rewrite confondra le chemin d'accès relatif avec un chemin de fichier au lieu d'un chemin d'URL et à cause de l' R
indicateur, vous finirez par être redirigé vers quelque chose comme:http://example.com/var/www/localhost/htdocs/subdir1
. Ce qui n'est évidemment pas ce que vous voulez.
C'est là RewriteBase
qu'intervient. La directive indique à mod_rewrite quoi ajouter au début de chaque chemin relatif. Donc si j'ai:
RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]
dans "subsubdir", aller à http://example.com/subdir2/subsubdir/foo
vraiment me servir http://example.com/blah/bar.php
. Le "bar.php" est ajouté à la fin de la base. Dans la pratique, cet exemple n'est généralement pas ce que vous voulez, car vous ne pouvez pas avoir plusieurs bases dans le même conteneur de répertoire ou fichier htaccess.
Dans la plupart des cas, il est utilisé comme ceci:
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
où ces règles seraient dans le répertoire "subdir1" et
RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]
serait dans le répertoire "subsubdir".
Cela vous permet en partie de rendre vos règles portables, vous pouvez donc les déposer dans n'importe quel répertoire et ne devez changer la base qu'au lieu d'un tas de règles. Par exemple, si vous aviez:
RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L]
RewriteRule ^blah2$ /subdir1/blah2.php [L]
...
de telle sorte que va http://example.com/subdir1/foo
servir http://example.com/subdir1/bar.php
etc. Et disons que vous avez décidé de déplacer tous ces fichiers et règles dans le répertoire "subsubdir". Au lieu de changer chaque instance de /subdir1/
en /subdir2/subsubdir/
, vous auriez pu simplement avoir une base:
RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...
Et puis, lorsque vous avez dû déplacer ces fichiers et les règles vers un autre répertoire, changez simplement la base:
RewriteBase /subdir2/subsubdir/
et c'est tout.