Ergonomie — Introduction à l'architecture d'un site web

Licence Informatique 3ème année

Alexandre Niveau — Jean-Marc Lecarpentier

Enseignement des technologies du Web

 

Ergonomie — Introduction à l'architecture d'un site web

Notes de cours

Travail personnel

Objectifs

Ce TP n'a pas de rapport avec le CM : il s'agit d'une introduction à l'architecture d'un site web, qui permet d'introduire les problématiques qui seront abordées ensuite en cours.

Exercice 1 — Architecture d’un site simple #

Attention, ceci n’est pas tout à fait l’exo 3 de la semaine dernière : il y a deux parties ajoutées avant l’ancienne troisième partie (qui est donc devenue la cinquième). À part ça rien n’a changé.

Récupérer cette archive. Elle contient un répertoire poemes, qui lui-même contient

  • un répertoire textes, avec les textes de quatre poèmes
  • un répertoire images, avec les images des poètes
  • un fichier donnees.php, qui déclare un tableau contenant des informations sur les poèmes (auteur, titre, image correspondante)

Le but de l'exercice est de réaliser un site présentant ces quatre poèmes. Un site plus conséquent utiliserait évidemment une base de données ; un des objectifs est de vous faire manipuler les tableaux PHP, et de vous faire travailler sur l'architecture d'un site indépendamment des problèmes spécifiques aux BD (connexion, erreurs de requêtes, etc.).

Une version naïve du site consisterait à créer un script PHP par page (donc un pour chaque poème + la page d'accueil). C'est une très mauvaise idée : il y a énormément de redondances entre les scripts, et si on veut rajouter un poème à la liste, c'est compliqué.

Une meilleure solution est de faire en sorte que le site ne soit généré que par un seul et même script principal, qui va choisir quoi afficher en fonction de l'URL.

Pour simplifier l'énoncé et l'exercice, on va utiliser un paramètre d'URL pour choisir le poème à afficher. Ce choix vous semble-t-il pertinent ?

Première partie : un site fonctionnel

  1. Placer le répertoire poemes sur le serveur, et créer un fichier index.php dans le répertoire. Mettre un modèle de page HTML de base dans le fichier index.php. Dans toute cette partie, on ne modifiera que ce fichier index.php : notre site va contenir plusieurs pages, mais toutes seront générées par cet unique script.
  2. Inclure le fichier donnees.php depuis le fichier index.php. On va ainsi pouvoir accéder aux informations sur les poèmes.
  3. Afficher une liste des titres des poèmes (en utilisant le tableau, bien sûr !).
  4. Récupérer le paramètre poeme dans l'URL, et si sa valeur correspond à l'une des quatre clefs (boheme, correspondances, bois, automne), alors on va afficher la page du poème correspondant : pour l'instant, afficher le titre du poème comme titre principal de la page (h1) et dans l'élément title de l'en-tête HTML.
  5. Ajouter à la page le texte du poème correspondant, et le nom de l'auteur en-dessous.
  6. Ajouter l'image correspondante, avec comme texte alternatif le nom de l'auteur.
  7. Transformer la liste des titres de poèmes en une liste de liens : un clic sur un poème mène à la « page » correspondante.
  8. Faire en sorte que s'il n'y pas de paramètre poeme dans l'URL, un message d'accueil soit affiché.
  9. Faire en sorte que si la valeur du paramètre poeme dans l'URL est erronée, un message d'erreur soit affiché.

Deuxième partie : une meilleure architecture

À ce niveau-là, le mini-site doit fonctionner correctement. Il n'est cependant pas très propre, car on a mélangé la logique et l'affichage. Pour bien faire, il faut séparer notre fichier en deux morceaux.

  • index.php va être le contrôleur, il ne s'occupera que d'analyser l'URL pour déterminer le poème désiré et récupérer les informations correspondantes dans les données. Il ne devra rien afficher lui-même : une fois son travail terminé, il se contentera d'inclure l'autre fichier.
  • On va créer un fichier squelette.php, qui au contraire ne s'occupera que de l'affichage. Il contiendra une page HTML « à trous » (on parle de template) : on n'utilisera PHP que pour afficher des variables. Les variables seront remplies au préalable par le contrôleur.

Créer un squelette pour les pages affichant un poème, et modifier index.php pour qu'il se comporte comme un contrôleur tel que décrit ci-dessus.

Créer un squelette pour les autres pages (accueil et erreur) si nécessaire, et adapter index.php. Remarque : si vous estimez que vos squelettes partagent trop de code HTML, n'hésitez pas à extraire des fragments communs, qui seront inclus depuis plusieurs squelettes (l'exemple typique est le pied de page).

Troisième partie : un peu d'objet

Le code est mieux structuré avec cette séparation contrôleur/squelette, mais la partie modèle est un peu pauvre avec son simple tableau de tableaux. Si on veut la faire évoluer — par exemple en associant plusieurs images à chaque poème, ou des commentaires, ou en ajoutant des pages pour les auteurs — cela va vite devenir du bricolage difficile à maintenir. On va essayer d'anticiper cela en encapsulant mieux les données dans des objets.

  1. Créer un fichier Poem.php et y définir une classe Poem, avec notamment les getters suivants (qui renvoient tous des chaînes de caractères) :
    • getTitle(), qui renvoie le titre du poème
    • getAuthor(), qui renvoie le nom de l'auteur
    • getImageUrl(), qui renvoie une URL (relative) vers l'image associée au poème
    • getHtmlText(), qui renvoie le texte du poème en HTML
    Remarque importante: les instances de Poem donnent des informations plus riches que les sous-tableaux (regarder les deux derniers getters). En effet, il n'est pas logique que ce soient le contrôleur ou le squelette qui connaissent les chemins vers les images ou la façon de récupérer le texte des poèmes. Ce sont des détails qui concernent le stockage des données. Comme on est en train de faire un refactoring, on va en profiter pour rendre cela plus propre.
  2. Inclure ce fichier Poem.php au début de donnees.php. Ensuite, toujours dans donnees.php, utiliser le tableau $donnees pour construire un nouveau tableau $donnees_obj avec les mêmes clefs, mais avec pour valeurs des instances de Poem (au lieu d'un sous-tableau). (N'oubliez pas la « remarque importante » plus haut.)
  3. À la fin du fichier, mettre unset($donnees); (pour pouvoir vérifier qu'on ne l'utilise plus), et modifier index.php et squelette.php pour qu'ils utilisent les instances de Poem stockées dans $donnees_obj (en n'oubliant pas la « remarque importante »).

Quatrième partie : transparence du stockage

Maintenant qu'on a traité les petits sous-tableaux, on va s'intéresser au grand tableau. Ça ne pose aucun problème d'utiliser un tableau comme « base de données » pour ce minuscule site, mais il n'est pas très satisfaisant que le reste du code dépende de ce choix d'implémentation. Si le site est amené à évoluer, notamment pour présenter un contenu plus dynamique, il risque de nécessiter l'emploi d'une vraie base de données — auquel cas il faudra aller modifier toutes les utilisations de $donnees_obj.

On va donc encapsuler notre tableau dans un objet, qui aura l'avantage de présenter une interface homogène quel que soit le choix concret d'implémentation du stockage. Les clefs de notre tableau (boheme, bois…) vont maintenant être considérés comme des identifiants.

  1. Créer un fichier PoemStore.php et y définir une classe PoemStore, possédant un attribut privé data que le constructeur initialise avec le tableau vide.
  2. Ajouter les méthodes suivantes :
    • createPoem(string $id, Poem $poem), qui ajoute un poème à la clef $id de l'attribut data ;
    • readPoem(string $id), qui renvoie le poème associé à la clef $id de l'attribut data si la clef existe, et null sinon (ce choix d'API est en cohérence avec la façon dont on utilise une base de données) ;
    • readAllPoems(), qui renvoie un tableau associatif identifiant ⇒ poème — c'est-à-dire le contenu de l'attribut data.
  3. Inclure le fichier au début de donnees.php. À la fin, créer une instance $store de PoemStore et utiliser le tableau $donnees_obj pour remplir $store.
  4. Supprimer la variable $donnees_obj (comme fait précédemment pour $donnees) et modifier le reste du code pour qu'il utilise $store et ses méthodes à la place.

À présent, notre code est plus robuste à un changement d'implémentation du stockage : il suffira de changer le contenu de PoemStore.php. Le changement sera transparent pour tout le reste de l'architecture.

Cinquième partie : recherche dans les poèmes

Faire en sorte que le site reconnaisse un paramètre recherche dans l'URL, qui permet de chercher une chaîne de caractères dans le texte des poèmes. Le site doit effectuer une liste de liens vers les poèmes correspondants, ou bien un message du type « Aucun poème ne correspond à votre recherche ». (Si nécessaire, la page des résultats de recherche pourra bien sûr faire l'objet d'un squelette spécifique.)

Ajouter un formulaire de recherche sur toutes les pages du site, qui va permettre d'exploiter le paramètre recherche.

Le script index.php commence (un peu…) à grossir : de fait, il est chargé de deux missions orthogonales, à savoir le choix de l'action à effectuer (afficher un poème, la page d'accueil, ou la page des résultats de recherche) et l'implémentation de cette action (remplir les trous du squelette, faire la recherche). La première mission est plutôt un travail de « routage » ou d'« aiguillage ». Essayez de séparer du contrôleur cette mission de routage.

Pour les rapides : une façon de vérifier la bonne séparation des responsabilités dans votre architecture est de faire en sorte que le programme principal puisse être appelé soit via HTTP, soit en ligne de commande.

  • Dans un premier temps, si on se contente de récupérer du HTML dans les deux cas, seul la partie « routage » devrait changer.
  • A priori on préférerait ne pas avoir de HTML dans le terminal ; on ne peut donc pas se contenter de faire inclure des squelettes au contrôleur. Implémenter un système de Displayers (comme cela a été fait dans de précédents TP) pour gérer les deux situations de manière propre.