Rewrite avec .htaccess
Par défaut, une url du type www.monsite.com/about.php va demander au serveur apache de servir le fichier about.php qui se trouve à la racine du site.
On peut cependant changer le comportement d'apache et lui dire que tous les appels au serveur seront redirigés vers index.php (par exemple) et c'est ce fichier qui lui fera appel à un système de route qui permettra de savoir quoi afficher.
Pour cela, le plus simple est d'ajouter un fichier .htaccess à la racine de votre site contenant le code suivant :
RewriteEngine On RewriteBase / #si ce n'est pas un répertoire RewriteCond %{REQUEST_FILENAME} !-d # Si ce n'est pas un fichier RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.+)$ index.php [QSA,L]
Reconnaître le chemin demandé
Une fois que ce fichier .htaccess est en place, il va falloir tester quel est le chemin demandé et appeler le fichier php correspondant.
Exemple simpliste.
Imaginons que l'on veuille que la requête http://www.monsite.com/toto permette de servir le fichier /templates/toto.php
Il nous suffira de tester, dans le fichier index.php, le chemin de l'url que l'on va pouvoir récupérer avec la fonction parse_url() de la manière suivante :
// parse_url() analyse une URL et retourne ses composants $parsed_url = parse_url($_SERVER['REQUEST_URI']); // soit l'url en question a un chemin et sinon le chemin est la racine $path = isset($parsed_url['path']) ? $parsed_url['path'] : '/'; // si le chemin est bien toto alors on fait appel au fichier /templates/toto.php if($path == "/toto") require_once($_SERVER["DOCUMENT_ROOT"].'/templates/toto.php');
Chemins plus complexes avec les expressions régulières
Comme vous vous en doutez, les éléments à afficher n'ont pas toujours des chemins aussi simples que "toto".
Il est classique que le chemin soit du type http://www.monsite.com/node/2567.
Mécanisme de reconnaissance d'un chemin complexe avec preg_match.
C'est ici qu'interviennent les expressions régulières. Elles vont permettre de reconnaître des "pattern".
Exemple de code utilisant un pattern correspondant à http://www.monsite.com/node/xxx en reprenant le code du dessus.
// parse_url() analyse une URL et retourne ses composants $parsed_url = parse_url($_SERVER['REQUEST_URI']); // soit l'url en question a un chemin et sinon le chemin est la racine $path = isset($parsed_url['path']) ? $parsed_url['path'] : '/'; // si le chemin correspond bien au pattern on fait appel au fichier node.php $pattern = '~^/node/([0-9]+)/?$~'; if (preg_match($pattern, $path)) require_once($_SERVER["DOCUMENT_ROOT"] . '/templates/node.php');
Récupération d'éléments du chemin toujours avec preg_match
Vous l'aurez compris, avant de faire appel au fichier qui va afficher notre node (/templates/node.php) il sera nécessaire de faire un appel en base de données pour récupérer les données qui correspondent à l'identité du node en question (2567 par expemple).
Pour "capturer" une partie du "pattern" on utilisera les (). Les résultats seront stockés dans le tableau donné en troisième argument à preg_match().
Le code deviendra alors :
// parse_url() analyse une URL et retourne ses composants $parsed_url = parse_url($_SERVER['REQUEST_URI']); // soit l'url en question a un chemin et sinon le chemin est la racine $path = isset($parsed_url['path']) ? $parsed_url['path'] : '/'; // si le chemin correspond bien au pattern on fait appel au fichier node.php $pattern = '~^/node/([0-9]+)/?$~'; if (preg_match($pattern, $path, $matches, PREG_OFFSET_CAPTURE)) { if(isset($matches[1][0])) { // Récupération des données via la classe Model $GLOBALS["node_data"] = Model::getNode($matches[1][0]); // Récupération des données via la classe Model $GLOBALS["node_data"] = Model::getNode($matches[1][0]); // Affichage des données require_once($_SERVER["DOCUMENT_ROOT"].'/templates/node.php'); } }
Bien entendu, ce code n'est qu'un exemple possible de mécanisme. Il ne gère pas les erreurs, ce qui sera nécessaire pour un code utilisable en production.
Router et architecture MVC (Modèle Vue Contrôleur)
- Modèle : la donnée,
- Vue : l'interface (html css principalement),
- Contrôleur : l'intelligence qui fait le lien entre la vue et le modèle.
Le contrôleur se situe entre le modèle et la vue. Il communique avec les deux pour répondre à une demande.
Le routeur choisit quel contrôleur (et quelle méthode sur ce contrôleur) gère la demande.