Vous êtes ici : Accueil > Référence HTML et JavaScript > Réécriture d'URL sans mod rewrite

Réécriture d'URL sans mod rewrite

Vous aimeriez utiliser la technique de l'url-rewriting, mais votre hébergeur n'a pas activé le module mod rewrite d'apache ? C'est pas grave : si vous avez la permission d'utiliser php (ou un autre langage serveur) et les fichiers htaccess, vous êtes sauvé.

Commençons par le début : c'est quoi l'url-rewriting ?

L'url-rewriting est une technique qui vise à créer des adresses URL fictives, plus belles à voir, plus agréables, pour vos pages dynamiques.

Avec les langages serveur comme php, les adresses du type http://www.monsite.com/article.php?article=37508&&page=2 ne sont pas rare. Avouez que cette adresse n'est pas très intuitive... Eh bien, l'url-rewriting a le pouvoir de la transformer, de manière totalement transparente aussi bien pour vous que pour le visiteur, en http://www.monsite.com/article37508-2.php ou même http://www.monsite.com/article35708-2/. Outre leur côté esthétique par rapport aux URL à rallonge classiques, elles favorisent également le référencement par les moteurs de recherche tels que Google.

Ce qui est magique, c'est que vous n'avez normalement pas besoin de modifier votre script de base index.php. IL n'y a que les liens à mettre à jour.

Nous allons dans un premier temps voir comment ce système de réécriture d'URL est mis en place grâce au module mod rewrite d'apache. Puis, ensuite, nous allons voir comment faire sans, puisque c'est le but premier de ce tutoriel.

Afin de comprendre et pouvoir mettre en pratique correctement les explications qui vont suivre, vous devez :

  • Avoir une bonne base en langage serveur (ici nous utiliserons php, mais le même principe peut être appliqué avec asp, jsp, coldfusion ou un autre langage s'exécutant côté serveur).
  • maîtriser les expressions régulières. Ceci est absolument indispensable car c'est les fondements même de l'url-rewriting. Pour être au clair à ce sujet, référez-vous à l'indispensable bible en la matière, à savoir expreg.com.
  • Connaître un minimum le fonctionnement du fichier .htaccess.
  • Et bien évidemment ... connaître le HTML même si ce n'est finalement pas très indispensable ici.

L'url-rewriting classique, avec le mod rewrite d'apache

Je ne vais pas m'étendre ici, car il existe déjà de très bons tutoriels expliquant comment fonctionne l'url-rewriting classique. Aussi, je me contenterai d'un simple et bref résumé.

Tout d'abord, l'activation du module de réécriture d'url se fait en ajoutant la ligne suivante dans le fichier .htaccess :

rewriteengine on

Ensuite, on définit une règle de réécriture grâce à la commande rewriterule :

rewriterule [expression_régulière] [remplacement]

Cette commande fonctionne comme un simple rechercher/remplacer par expression régulière : Chaque URL entré par l'utilisateur satisfaisant le masque indiqué provoquera sur le serveur l'appel du fichier spécifié comme chaîne de remplacement. L'utilisateur verra affiché l'URL non remplacée, alors que le fichier réellement appelé sur le serveur pourra être tout autre. On marque les références arrières d'expressions parenthésée par $1, $2, ... $n.

Voilà en quelques lignes comment fonctionne la réécriture d'url de manière habituelle. Pour plus d'informations, demandez à Google.

L'url-rewriting avec php et sans mod rewrite

Nous voici donc maintenant dans la partie du tutoriel qui vous intéresse le plus. Comment faire de la réécriture d'url sans ce satané module mod rewrite d'apache ?

Tout le problème demeure bien là : est-il possible de s'en passer ?

La réponse est bien sûr oui; sinon à quoi servirait ce tutoriel ? Il est bien sûr évident que la solution proposée ici n'est pas si simple ni si solide que la version classique offerte par apache. Mais elle fonctione, c'est l'essentiel n'est-ce pas ?

Il est temps que j'arrête de vous faire mariner. Nous allons maintenant démarrer sans plus attendre.

Première étape : la page d'erreur 404

Nous allons commencer par créer une page d'erreur 404 particulière. Lorsque celle-ci sera appelée, elle aura pour tâche de vérifier l'url entrée, et, si elle correspond à un modèle connu, elle va afficher la page désirée. Dans le cas contraire, on aura affaire à une page d'erreur 404 normale qui ne fera rien de plus que d'afficher un gentil petit message comme quoi la page n'a pas étée trouvée à votre visiteur.

Nous allons donc commencer par enregistrer notre nouvelle page d'erreur dans le .htaccess, au moyen de la ligne suivante :

ErrorDocument 404 /erreur404.php

N'oubliez pas d'adapter éventuellement le chemin d'accès à cette page d'erreur.

Deuxième étape : Comparer l'URL appelée

Dans notre page d'erreur 404, nous allons vérifier l'URL que l'utilisateur désire obtenir. L'URL exacte telle que saisie ou validée peut être obtenue en php dans la variable $_SERVER['REQUEST_URI']. Elle contient l'URL demandée depuis la racine (/) du serveur. Ne confondez surtout pas avec $_SERVER['PHP_SELF'] ou $_SERVER['SCRIPT_NAME'] qui contiennent le nom du fichier php et nom l'adresse URL réelle demandée par le visiteur.

IL suffira donc de comparer $_SERVER['REQUEST_URI'] avec une ou plusieurs expressions régulières. Pour cela, il faut utiliser les fonctions habituelles dédiées à cette tâche : ereg, eregi, preg_match, ...

Voici un exemple qui intercepte les adresses du type /articleN.php et /articleN-pageN.php :


<?php
$url = $_SERVER['REQUEST_URI']; // On récupère l'adresse demandée

// ON vérifie si elle est de la forme /articleN.php où N est un nombre
if (preg_match('#^/article(\d+)\.php$#', $url, $match)) {
// Traitement de la demande pour cette URL particulière
}

// On vérifie si elle est de la forme articleN-pageN.php 
else if (preg_match(('#^/article(\d+)-page(\d+).php$#', $url, $match)) {
// Traitement de la demande pour cette URL particulière
}

// Sinon, une page d'erreur 404 normale affichant un message bidon
else {
echo "Cette page n'existe pas !"; 
}
?>

Et voilà, nous avons déjà une page 404 intelligente qui réagit en fonction de l'URL demandée. A ce stade, vous avez fait le plus dur.

Troisième étape : Inclusion de la page demandée

Maintenant, il ne reste plus grand chose à faire : afficher une page adéquate en fonction de ce qui est demandé. Pour cela, trois étapes :

  • Récupérer la valeurs des paramètres issus de l'expression régulière
  • Attribuer ces valeurs à la variable $_GET pour qu'elles puissent être prises en compte par le script inclus
  • Inclure la page à afficher au moyen de la fonction include.

Nous allons donc récupérer les données du tableau $match dans un premier temps :


$numero_article = $match[1]; // le numéro d'article se trouve dans la première parenthèse capturante

Puis nous allons fixer la valeur de $_GET['article'], afin qu'il contienne l'information comme si la page avait été appelée par la voie normale avec les paramètres dans l'URL. Ensuite, nous allons inclure la page index.php qui pourra ainsi s'exécuter comme d'habitude. Pour terminer, afin d'être sûr que tout se passe bien, nous quittons le script avec exit.

A ce stade, le code devient le suivant :


<?php
$url = $_SERVER['REQUEST_URI']; // On récupère l'adresse demandée

// ON vérifie si elle est de la forme /articleN.php où N est un nombre
if (preg_match('#^/article(\d+)\.php$#', $url, $match)) {
// Récupération des valeurs de l'expression régulière
$numero_article = $match[1]; // Le numéro d'article se trouve dans la première parenthèse de l'expression

// On fixe les valeurs du tableau $_GET afin qu'il contienne les mêmes valeurs que si le script avait été appelé par la voie normale
$_GET['article'] = $numero_article;
$_GET['page'] = $page;

// ON inclut la page index.php et on termine le script
include("index.php");
exit();
}

// On vérifie si elle est de la forme articleN-pageN.php 
else if (preg_match(('#^/article(\d+)-page(\d+).php$#', $url, $match)) {
// Récupération des valeurs de l'expression régulière
$numero_article = $match[1]; // Le numéro d'article se trouve dans la première parenthèse de l'expression
$page = $match[2]; // le numéro de page se trouve dans la deuxième parenthèse

// On fixe les valeurs du tableau $_GET afin qu'il contienne les mêmes valeurs que si le script avait été appelé par la voie normale
$_GET['article'] = $numero_article;
$_GET['page'] = $page;

// ON inclut la page index.php et on termine le script
include("index.php");
exit();
}

// Sinon, une page d'erreur 404 normale affichant un message bidon
else {
echo "Cette page n'existe pas !"; 
}
?>

Pinaillons encore un peu...

Et voilà, c'est terminé. la page 404 redirigeante fonctionne. Vous pouvez désormais appeler /articleN.php et /articleN-pageN.php à la place de /index.php?article=N et /index.php?article=N&page=N.

Parce que je suis un bon pinailleur, je vais vous dire que ce n'est pas tout à fait fini. Il reste un détail à régler, et il peut être de taille. Envoyons une requête HTTP à la page /articleN.php que nous venons de « créer » :


HTTP/1.1 404 Not Found
Content-Type:text/html

Le serveur renvoie une indication comme quoi votre page, qui « existe virtuellement » pourtant, n'existe pas, comme s'il s'agissait d'une page d'erreur 404 normale.

Cela est simple à comprendre : nous sommes passés par une page d'erreur 404 !

Et alors ?

Conséquence de ce « détail » qui n'en est en réalité pas un : vos pages affichées par le biais de cette technique ne seront pas référencés par les moteurs, et, de plus, seront parfois remplacées par une boîte de dialogue du navigateur indiquant que la ressource est introuvable ou que sais-je encore liée à une page d'erreur 404 habituelle.

La solution

Heureusement pour nous, php permet de modifier la ligne de statut renvoyée par la requête HTTP. Vous ne le saviez peut-être pas, mais vous avez en plus sans nul doute déjà utilisé la fonction qui permet de le faire : header !

En effet, grâce aux deux lignes suivantes :


header("HTTP/1.1 200 OK");
header("Status:200 OK");

Et voilà !

Voici le code repris de l'exemple précédent :


<?php
$url = $_SERVER['REQUEST_URI']; // On récupère l'adresse demandée

// ON vérifie si elle est de la forme /articleN.php où N est un nombre
if (preg_match('#^/article(\d+)\.php$#', $url, $match)) {
// Récupération des valeurs de l'expression régulière
$numero_article = $match[1]; // Le numéro d'article se trouve dans la première parenthèse de l'expression

// On fixe les valeurs du tableau $_GET afin qu'il contienne les mêmes valeurs que si le script avait été appelé par la voie normale
$_GET['article'] = $numero_article;
$_GET['page'] = $page;

// ON modifie le code de statut HTTP
header("HTTP/1.1 200 OK");
header("Status:200 OK");

// ON inclut la page index.php et on termine le script
include("index.php");
exit();
}

// On vérifie si elle est de la forme articleN-pageN.php 
else if (preg_match(('#^/article(\d+)-page(\d+).php$#', $url, $match)) {
// Récupération des valeurs de l'expression régulière
$numero_article = $match[1]; // Le numéro d'article se trouve dans la première parenthèse de l'expression
$page = $match[2]; // le numéro de page se trouve dans la deuxième parenthèse

// On fixe les valeurs du tableau $_GET afin qu'il contienne les mêmes valeurs que si le script avait été appelé par la voie normale
$_GET['article'] = $numero_article;
$_GET['page'] = $page;

// ON modifie le code de statut HTTP
header("HTTP/1.1 200 OK");
header("Status:200 OK");

// ON inclut la page index.php et on termine le script
include("index.php");
exit();
}

// Sinon, une page d'erreur 404 normale affichant un message bidon
else {
echo "Cette page n'existe pas !"; 
}
?>

En conclusion

Cette technique permet d'utiliser la réécriture d'url sans avoir recours au module mod rewrite d'apache. IL est évident que, dans le cas ou celui-ci est installé, il faut le privilégier à la méthode expliquée ci-dessus, pour des raisons de maintenabilité du code. Cepdendant, cela reste une bonne béquille de secours, car vous pouvez en théorie faire n'importe quoi dans le script php de la page 404.

Vous êtes ici : Accueil > Référence HTML et JavaScript > Réécriture d'URL sans mod rewrite

Dernière modification de cette page : Jeudi 25 mai 2006 00:30
Haut de page  •  Contact  •  RSS  •  Valide XHTML 1.0