Aller aux commentaires

L'URL Rewriting et Free

L'url rewriting consiste en une ré-écriture de l'adresse d'une page générée dynamiquement en php par exemple, de façon à la rendre plus lisible pour l'internaute et plus digeste pour les moteurs de recherche, facilitant ainsi son référencement.
Habituellement, l'url rewriting nécessite la création d'un fichier dédié sur le serveur qui contient l'ensemble des règles de ré-écriture pour toutes les pages du site. Or le FAI Free n'autorise pas cette manipulation, et nous oblige à contourner cette restriction si l'on souhaite tout de même pratiquer l'url rewriting.
L'article qui suit vise à expliquer en détail la démarche à adopter pour obtenir des adresses "propres" sur un site hébergé chez Free, avec un exemple concret en fin d'article..

Intro

Jettez un oeil sur l'url de cette page, et vous constaterez que les variables Php nécéssaires à son affichage ne sont pas présentes ; en tout cas pas sous leur forme standard, de type
http://site.fr/page.php?variable1=valeur1&variable2=valeur2,
mais sous la forme
http://site.fr/page/valeur1/valeur2.
Ce nouveau format d'url est la première chose à définir, en sachant qu'il s'agit d'un montage total, c'est-à-dire que l'on peut ajouter autant d'arguments que l'on veut pour "embellir" notre url. Il faut simplement qu'à un moment donné apparaissent les variables "utiles" que l'on souhaite transmettre au script!
Ensuite il suffit de modifier les liens pointant sur la page et de modifier également la manière de récupérer les variables puisque la méthode $_GET n'est plus disponible. Voyons tout ça en détail...

Choisir un format d'url.

Je vais reprendre mon exemple générique de page définie par l'adresse
http://site.fr/page.php?variable1=valeur1&variable2=valeur2,
qui nécessite donc 2 variables à transmettre au script Php.
J'insiste sur le fait que le point de départ est bien le choix d'un format d'url à partir duquel on éffectue les adaptations nécéssaires, et non l'inverse! Je décide donc que je souhaite obtenir après url rewriting l'adresse:
http://site.fr/page/valeur1/valeur2.

J'aurais pu cependant vouloir obtenir une adresse de type:
http://site.fr/page/valeur1/valeur2/valeur3.html, avec une troisième variable inutile au script mais optimisant les informations pour le visiteur et les moteurs de recherche, avec un .html simulant un fichier html. Dans ce cas j'aurais tout simplement ignoré ces paramètres dans mon script Php, puisque leurs présences n'est dûe qu'à des facteurs autres que le passage d'informations pour la génération dynamique de ma page.

Récupérer et traiter les variables

Dans notre url ré-écrite, vous remarquez que l'extention .php du fichier page.php a disparu. Cela est possible grâce à la directive MultiViews de Apache qui est activée chez Free, et qui permet entre autre au serveur de "choisir" le fichier le plus approprié si aucune extention n'est spécifiée. Notez bien que si un répertoire nommé page se trouvait à la racine du serveur, celui-ci serait privilégié par rapport au fichier page.php! Il faut donc faire en sorte de ne pas avoir de fichiers et de dossiers portant le même nom pour éviter toute ambiguité!

C'est donc bien page (dans notre exemple) qui affiche la page, et on en déduit que les variables, ou plutôt leurs valeurs, commencent avec le / juste après page.
Comme on l'a déjà vu, les variables ainsi transmises via l'url ne sont plus accéssibles dans le code par le tableau $_GET[''] car il n'y a plus de paire nom/valeur, ni d'ailleurs de ? pour indiquer le début de la chaine des valeurs passées au script. Et c'est là que ça devient amusant!

Voici le début du code:

// étape 1
     $url = $_SERVER['PATH_INFO'];
// étape 2
     $get_url = explode("/",$url);
Il s'agit donc de récupérer les valeurs présentes dans l'url:
  • dans l'étape 1, on stocke dans une variable $url la chaine des valeurs transmises qui est fournie par la variable prédéfinie $_SERVER['PATH_INFO'], et qui commence avec le / placé après page. Dans notre exemple, $url vaut donc /valeur1/valeur2.
  • Dans l'étape 2, on isole chaque valeurs et on les stocke dans un tableau $get_url. La fonction explode() permet de séparer une chaine sur un séparateur, ici le /.
    Dans notre exemple, on se retrouve donc avec un tableau indicé $get_url, qui contient $get_url[0]="", $get_url[1]="valeur1" et $get_url[2]="valeur2".

Vous l'aurez compris, $get_url[0]="" ne nous sert à rien, $get_url[1]="valeur1" est l'équivalent d'un $_GET['variable1'] dans le cas d'une url "normale", et $get_url[2]="valeur2" est l'équivalent d'un $_GET['variable2'].

Le plus gros du travail est fait, on retrouve bien dans notre script les valeurs passées dans l'url nécessaires à son bon fonctionnement, pour les requêtes vers la base de données ou autre. Bien sur rien n'empêche de renommer tout ça pour y voir plus clair, par exemple:

$var1 = $get_url[1];
$var2 = $get_url[2];
Dans le cas particulier où vous décidez d'ajouter un .html dans votre format d'url, il faudra alors le supprimer pour récupérer la dernière valeur de l'url. C'est la fonction substr() qui vous sera utile car elle permet de choisir les caractères qu'on veut conserver ou éliminer dans une chaine; par exemple :
// suppression des 5 derniers caractères de la chaîne (.html)
$var2 = substr($get_url[2], 0, -5);

Traiter les liens

Notre fichier est maintenant prêt à recevoir les valeurs transmises dans l'url ; encore faut-il les lui envoyer correctement! Il ne reste plus pour cela qu'à modifier les liens qui pointent dessus.
Ils doivent tout simplement correspondre au format que l'on a défini, soit dans notre exemple:

<a href="http://site.fr/page/valeur1/valeur2">texte du lien</a>
Le serveur comprendra alors qu'il doit "afficher" le fichier page.php, et celui-ci traitera les arguments passés dans l'url.

Bien sûr l'exemple que j'ai développé ici est assez basique, mais la technique est la même pour des URL Rewriting plus complexes, si ce n'est que le travail d'adaptation des valeurs passées par l'url pour leur utilisation dans le script est parfois périlleux, mais php fournis suffisament de fonctions de traitement des chaînes de caractères pour s'en sortir.

Script complet

NB: si vous souhaitez tester vos scripts en local sur Wamp, une petite modification du fichier de configuration d'Apache httpd.conf est nécessaire, sans quoi rien ne fonctionnera! Pour ce faire, commencer par ouvrir ce fichier, puis faite une recherche (ctrl F) sur le terme multiview. Cherchez ensuite la ligne "#Options Indexes FollowSymLinks MultiViews " et dé-commentez la en supprimant le "#".

Dans cet exemple, nous allons réaliser un script de news avec catégories. Toutes les requêtes pour accéder à un article ou une catégorie passeront par un fichier "tour de contrôle", qui déterminera, en fonction des valeurs transmises à l'url, le fichier à inclure.

Le fichier index.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
	<title>Accueil</title>
	<link rel="stylesheet" media="screen" type="text/css" href="structure.css"/>
</head>

<body>

	<h1>Page index</h1>

	<a href="news/">Lien 1 : Afficher tous les articles</a><br/><br/>
	<a href="news/categorie/musique">Lien 2 : Afficher tous les articles d'une catégorie</a><br/><br/>
	<a href="news/article/1-titre-de-l-article">Lien 3 : Afficher un article</a>

</body>
</html>

Rien d'exceptionnel dans ce fichier, si ce n'est la façon dont sont définis les liens. Normal puisque nos Url sont ré-écrites selon les critères que nous avons choisis.
En fait toutes ces Url appellent le fichier news.php, dont l'extention est supprimée.

Le fichier news.php

<?php

/* URL REWRITING --------------------------------------------- */
/* traitement de l'url pour récupérer les variables ---------- */

	// recup des arguments de l'url ( -> $get_url_arg = /string.. )
	$get_url_arg = $_SERVER['PATH_INFO'];
	
	// séparation des arguments; chacun devient un élément du tableau $get_arg:
	// $get_arg[0]=/ ; $get_arg[1]=string1 ; $get_arg[2]=string2 ; ...
	$get_arg = explode("/",$get_url_arg);   
	
/* INCLUDES en fonction des variables reçues par l'url ------- */

	switch ($get_arg[1]){	
		
		// URL -> http://.../news/categorie/nomCategorie
		case "categorie":	
			// recupérer le nom de la catégorie
			$cat = $get_arg[2];
			// inclure le fichier
			include("news_categorie.php");
			break;
	
		// URL -> http://.../news/article/1-titre-de-l-article
		case "article":
			// isoler l'identifiant de l'article
			$get_id_news = explode("-",$get_url[2]);
			$id_news = $get_tabIdNews[0];			
			// inclure le fichier
			include("news_article.php");
			break;

		case "":
			// inclure le fichier
			include("news_all.php");
			break;
			
		default:
		// URL -> http://.../news/n'importe quoi
			// inclure le fichier
			include("news_all.php");
	}
	
?>

Ce fichier est notre "tour de contrôle": toutes les requêtes pour afficher les pages de la section news passent par lui, et il définit les fichiers à inclure en fonction des arguments trouvés dans l'url.
Le second argument (categorie, article ...) est précisement celui qui détermine le fichier à inclure; les arguments suivant ont parfois besoin d'un traitement, pour isoler l'id d'un article par exemple.
On notera que les noms des fichiers inclus n'ont pas d'importance puisqu'ils n'apparaissent pas dans l'url.

Le fichier news_categorie.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
	<title>News > Catégorie > <?php echo $cat ?></title>
	<link rel="stylesheet" media="screen" type="text/css" href="structure.css"/>
</head>

<body>

	<h1>Catégorie: <?php echo $cat ?></h1>
	<a href="../../index.php">Retour index</a>
<?php
	// requête pour récupérer la liste des articles qui correspondent à la catégorie $cat
?>
</body>
</html>

Ce fichier sert à afficher les articles qui appartiennent à la catégorie définie.
Dans le fichier news.php, on a isoler le titre de la catégorie, qui permet d'éffectuer la requête sur la base de données pour récupérer les articles adéquat.
On note que le lien de retour à la page d'accueil se définit comme si l'on devait remonter 2 répertoires. L'url est construite de telle manière que l'on simule que le fichier news_categorie.php est situé 2 répertoires au dessus de l'index (news puis categorie). Une façon d'éviter les erreurs est d'écrire les liens en absolu et non en relatif comme ici.

Le fichier news_article.php

<?php
	// requete sur la table des articles pour récupérer l'article en fonction son identifiant $id_news
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
	<title>News > Titre de l'article</title>
	<link rel="stylesheet" media="screen" type="text/css" href="structure.css"/>
</head>

<body>

	<h1>Titre de l'article</h1>
	<a href="../../index.php">retour index</a>

</body>
</html>

Ce fichier sert à afficher un article, dont l'identifiant a été récupéré dans news.php.
Avec cet identifiant, il ne reste plus qu'à effectuer une requête pour récupérer son contenu, sa date, son auteur, etc...

Le fichier news_all.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
	<title>News > toutes</title>
	<link rel="stylesheet" media="screen" type="text/css" href="structure.css"/>
</head>

<body>

	<h1>News: toutes</h1>
	<a href="../index.php">Retour index</a>
<?php
	// requete pour récupérer l'ensemble des articles
?>
</body>
</html>

Ce fichier sert à afficher l'ensemble des articles.

Évidement l'exemple développé est basique, mais permet de bien appréhender la mécanique de la simulation de l'url rewriting. Vous pouvez télécharger une archive Zip contenant l'ensemble des fichiers.

Télécharger

Ajouter votre commentaire