Le module URL Rewriting n’est pas activé par défaut avec Apache. Dans le cas d’un hébergement mutualisé, c’est le prestataire qui décide de sa disponibilité. Si au contraire, vous êtes maître de votre installation, vous pouvez vous en charger vous même.

Installation du module

La procédure d’installation et d’activation du module est assez semblable selon votre installation (système d’exploitation, paquets de la distribution ou compilation manuelle, …).

Ces modifications s’appliquent dans le fichier de configuration d’apache, généralement httpd.conf, ou apache*.conf (où * peut correspondre à la version installée).

La plupart du temps, il suffit de rendre actives les lignes suivantes, en supprimant le caractère # en début de ligne :

  1. LoadModule rewrite_module modules/mod_rewrite.so
  2. AddModule mod_rewrite.c

Si vous ne les trouvez pas, il est possible que les modules soient localisés dans un autre répertoire que module/ sur votre installation : vérifiez ce point, sinon ajoutez-les, tout simplement !

Si vous avez compilé Apache par vous même, vous aurez peut-être à reprendre cette installation en ajoutant le paramètre --enable-rewrite (ou --enable-rewrite=shared) lors de l’étape de configuration.

Enfin, vous devrez recharger apache, généralement avec l’une de ces commandes : apache2 -k restart, apachectl -k restart, ou encore /etc/init.d/apache restart. Sous windows, il vous suffira d’utiliser les raccourcis graphiques.

Un premier test

Généralement, les règles de modification des URLs sont placées dans un fichier .htaccess (pour une installation standard), qui permet d’ajouter des directives qu’Apache appliquera au répertoire dans lequel se trouve le fichier.

Créez un fichier .htaccess à la racine de votre site internet et placez-y ces quelques lignes :

  1. <IfModule mod_rewrite.c>
  2. RewriteEngine On
  3. RewriteRule ceci_est_un_test /index.html
  4. </IfModule>

Ces lignes auront normalement pour effet d’afficher la page d’accueil (index.html) si vous essayer d’afficher ceci_est_un_test. Essayons maintenant de comprendre ces quelques lignes…

La condition <IfModule mod_rewrite.c> indique à Apache qu’il doit vérifier que le module est disponible avant de tenter d’appliquer les règles placées entre les deux balises. La directive RewriteEngine On permet d’indiquer que le module Url Rewriting doit être activé pour ce répertoire. Enfin, la directive RewriteRule sert à enregistrer une règle de conversion d’URL. La chaine de caractères avant l’espace indique le format de l’url recherchée, l’autre indique l’adresse réellement sur le serveur.

Ces règles sont définies à l’aide de la syntaxe des expressions régulières.

Les règles

Les expressions régulières permettent de rechercher des chaines de caractères variables.

Caractères spéciaux

Certains caractères des expressions régulières portent un sens particulier :

  • ^ : indique que nous sommes en début de ligne, ou au début de la chaîne de caractères. Cependant, entre crochets, la signification est différente,
  • $ : indique lui que nous sommes en fin de ligne, ou de chaîne,
  • . : remplace tout caractère inconnu,
  • \ : échape un caractère utilisé dans la syntaxe regex. Par exemple, pour utiliser un point, la syntaxe est \..

Ainsi, pour rechercher la chaine index.html, l’expression régulière à utiliser est ^index\.html$, Apache n’appliquera alors pas la règle si l’adresse demandée est quelquechose-index.html ou encore index.html-autrechose.

Les classes de caractères

Les classes de caractères servent à rechercher un des caractères parmi un ensemble, une classe s’écrit entre crochets. Voici quelques exemples de classes :

  • [éèê] : signifie que l’on cherche le caractère é, ou è ou encore ê,
  • [a-z] : signifie que l’on cherche n’importe quelle lettre en minuscules,
  • [a-zA-Z] : signifie que l’on cherche n’importe quelle lettre, il est possible de faire des combinaisons plus plus personnelles, par exemple [a-gA-Gn-zN-Z] signifie que l’on cherche une lettre comprise entre a et g et entre n et z,
  • [0-9] : signifie donc que l’on cherche un chiffre,
  • enfin, il est possible de rechercher n’importe quel caractère sauf certains en ajoutant le caractère ^ en début de classe : [^a-zA-Z] signifie que l’on recherche tout caractère n’étant pas une lettre.

Les captures

Vous pouvez avoir besoin de réutiliser certaines informations de l’adresse recherchée pour indiquer l’adresse réelle de votre page, par exemple, pour remplacer glossaire-a.html en glossaire.php?lettre=a. on utilise alors les parenthèses de capture (). Ainsi, chaque extrait de la chaine trouvée entre () pourra être utilisée dans l’adresse de remplacement avec une variable numérotée $n (où n correspond au numéro de la capture).

Par exemple :

  1. RewriteRule ^glossaire-([a-z])\.html$ glossaire.php?lettre=$1

Les quantificateurs

Les quantificateurs permettent d’indiquer la répétition d’un caractère, c’est à dire le nombre de fois où on souhaite les retrouver.

Voici les principaux quantificateurs :

  • ? : 0 ou 1 caractère (c’est à dire que le caractère n’est pas obligatoire),
  • * : 0 ou plusieurs caractères (le caractère peut ne pas être trouvé ou trouvé un nombre infini de fois à la suite),
  • + : 1 ou plusieurs caractères (le caractère doit être trouvé, mais le nombre de fois à la suite n’a pas d’importance),
  • {n} : le caractère doit être trouvé exactement n fois,
  • {n,m} : le caractère doit être trouvé entre n et m fois,
  • {n,} : le caractère doit être trouvé n fois ou plus.

Voici quelques exemples d’utilisation :

  • index\.html? : on recherche index.htm ou index.html,
  • .+\.html$ : on recherche n’importe quelle adresse dont l’extension est .html,
  • glossaire-[a-z]+\.html : cette fois, notre adresse peut être utilisées pour plusieurs lettres (par exemple, glossaire-aa.html).

L’alternative

Le dernier caractère dont nous allons parler est |, il signifie “ou” quand il est utiliser à l’intérieur d’une capture, par exemple (index|home|accueil)\.html permet de rechercher index.html, home.html ou accueil.html.

Les réécritures conditionnelles

La réécriture conditionnelle permet de limiter le cas dans lesquels s’appliquent certaines règles. Vous pouvez utiliser une réécriture conditionnelle pour interdire l’utilisation d’images enregistrées sur votre serveur depuis d’autres pages, ou vérifier d’abord si la page existe rééllement avant d’essayer de transformer l’adresse.

La directive d’Apache à utiliser est RewriteCond, vous devrez généralement effectuer des tests sur les variables d’environnement d’apache, par exemple %{REQUEST_FILENAME} pour tester l’adresse demandée.

Voici comment tester l’existance du fichier avant de rediriger :

  1. RewriteCond %{REQUEST_FILENAME} !-f
  2. RewriteCond %{REQUEST_FILENAME} !-d
  3. RewriteRule (.+)\.html$ index.php?page=$1

Voici quelques autres exemples d’utilisation :

Ici, l’adresse IP 127.0.0.1 sera, quelque soit l’adresse tapée (.*) redirigé vers inderdit.html.

  1. RewriteCond %(REMOTE_ADDR) ^127.0.0.1$
  2. RewriteRule .* /interdit.html

On peut rediriger les utilisateurs d’internet explorer vers le site de Mozilla :

  1. RewriteCond %(HTTP_USER_AGENT) MSIE
  2. RewriteRule .* http://www.mozilla.org

Ou encore interdire le hot linking, c’est à dire, l’utilisation d’images hébergées sur votre site depuis un autre :

  1. RewriteCond %(HTTP_HOST) [^(http://www.martiusweb.net)]
  2. RewriteRule (.+)\.(jpg|gif|png)^ /interdit.$1

Les drapeaux

Les drapeaux permettent de modifier partiellement le comportement d’une directive d’Apache. Un drapeau est placé entre crochets à la fin d’une directive. Vous pouvez cumuler les drapeaux en les séparant par des virgules.

Voici la liste des principaux drapeaux :

NC : permet de rendre la règle insensible à la casse (c’est à dire qu’aucune différence ne sera faite entre les minuscules et les majuscules),

L : permet d’indiquer à Apache que la règle appliquée est la dernière. En effet, tant que Apache ne rencontrera pas ce drapeau, il tentera de réécrire à nouveau l’adresse obtenue. Par exemple :

  1. RewriteRule accueil\.html$ accueil.php
  2. RewriteRule accueil\.php$ index.php?page=accueil

En demandant l’adresse accueil.html, celle-ci sera réécrite deux fois. Elle sera en premier transformée en accueil.php, puis en index.php?page=accueil. Pour interdire la deuxième réécriture, vous ajouterez le drapeau [L] à la fin de la première règle :

  1. RewriteRule accueil\.html$ accueil.php [L]
  2. RewriteRule accueil\.php$ index.php?page=accueil

G : Permet d’indiquer que la page n’est définitivement plus disponible (gone), ceci correspond au statut HTTP 410,

F : envoie le statut HTTP 403 indiquant que l’accès à la page est interdit,

R ou R=n : envoie le code statut HTTP n, par exemple, pour indiquer qu’une page à changé d’adresse, vous pouvez écrire une règle comme celle-ci :

  1. RewriteRule article_urlrewriting.html$ /post/Url-Rewriting [R=301,L]

N : Apache reprendra l’analyse de l’adresse depuis le début, en utilisant la dernière adresse transformée obtenue. Attention, l’utilisation de ce drapeau peut causer une boucle infinie (une règle dirigeant Apache vers une autre et vice-versa, pensez alors à utiliser le drapeau L),

C : lorsqu’une règle comportant ce drapeau est vérifiée, apache analysera l’adresse transformée avec la requête suivante, si celle-ci possède également ce drapeau, si la règle n’est pas vérifiée, Apache passera à la première règle suivante ne comportant pas se drapeau.

Adresse de base

Dans certains cas, il peut être nécessaire de préciser à Apache le répertoire de base dans lequel nous travaillons à l’aide de la directive RewriteBase.

Conclusion

L’utilisation des règles de réécriture d’URL permettent d’améliorer le référencement de vos pages par les moteurs de recherche ou encore la mémorisation par le visiteur, qui pourra comprendre plus facilement l’adresse.

Pour en savoir plus sur les expressions régulières, je vous invite à consulter le manuel de PHP qui offre une introduction à la syntaxe des expressions régulière très complète.

Pour en savoir plus sur le module URL Rewriting d’Apache, consultez la page de manuel à ce sujet.