Évaluation 2 : Le livre d'or
Sommaire
Introduction
Dans les précédents TP, nous avons vu les formulaires et la base de données (TP 2), l'organisation du code avec un entry-point (TP 3), la session et les cookies (TP 4), la protection de pages (TP 5) et sa version sérieuse avec les utilisateurs en base (TP Authentification).
Vous avez atteint un deuxième point étape. Ce mini projet est une synthèse évaluée de ces apprentissages. Il n'y aura pas de procédure pas à pas, à vous de mobiliser vos connaissances.
Le sujet est calibré pour une séance de 2 heures, README et rendu compris. Pour tenir ce temps : le script SQL du livre d'or vous est fourni (voir plus bas), et vous pouvez (c'est conseillé) repartir de la structure de votre TP 3 et du code de connexion de votre TP 5. Gardez 20 minutes en fin de séance pour le README et le rendu.
TP évalué - Barème indicatif (Total 20 points + Bonus)
La réalisation de ce TP sera évaluée de la manière suivante :
- Structure (4 points)
- Entry-point unique (
index.php) avec whitelist de pages : 2 points. - Organisation en dossiers (
common/,pages/,public/,utils/) : 1 point. - Header / footer communs inclus une seule fois : 1 point.
- Entry-point unique (
- Le formulaire (3 points)
- Formulaire en
POST(pseudo + message) : 2 points. - Contrôle de la saisie avec
isset()(pas d'erreur si champs vides) : 1 point.
- Formulaire en
- La base de données (4 points)
- Script fourni importé et connexion PDO sortie dans un fichier inclus (
utils/db.php) : 1 point. - Enregistrement du message par un
INSERTen requête préparée : 2 points. - Liste des messages lue en base (
SELECT) et affichée avec une boucle : 1 point.
- Script fourni importé et connexion PDO sortie dans un fichier inclus (
- L'espace admin (4 points)
- Page de connexion (login + mot de passe, en dur autorisé ici) : 1 point.
- État de connexion en
$_SESSION, avecsession_start()géré dans l'entry-point : 1 point. - Page admin accessible uniquement connecté (redirection sinon) : 1 point.
- Déconnexion fonctionnelle : 1 point.
- Qualité (2 points)
- Code indenté, organisation propre, liens de navigation cohérents : 2 points.
- Le README.md (3 points)
- Présent à la racine et complet (comme défini dans l'évaluation 1) : 3 points.
- Bonus challenge (2 points)
- La suppression de messages et le compteur de messages (voir la fin du sujet).
Attention à la sécurité
Une valeur qui vient de l'utilisateur ($_GET, $_POST) ne doit jamais être concaténée dans une requête SQL. Un seul oubli et c'est une injection SQL : ce point sera regardé de très près lors de la correction.
Vous avez à votre disposition l'ensemble des documents nécessaires :
- Le complément de cours PHP
- Le complément de cours SQL
- TP 2. Jouer avec les formulaires
- TP 3. Structurer mon code
- TP 4. Utiliser la session
- TP 5. Protéger des pages, première partie
- TP Authentification : les bonnes pratiques
Le projet
Vous allez réaliser un livre d'or : les visiteurs laissent un message, les messages sont enregistrés en base de données et s'affichent sur la page d'accueil, et un espace d'administration est protégé par un mot de passe.
- La base de données :
- Créer une base
livre_oret y importer le script fourni ci-dessous (tablemessages). - Sortir la connexion PDO dans
utils/db.php, inclus une seule fois depuis l'entry-point.
- Créer une base
Le script SQL fourni
CREATE TABLE messages (
id INT AUTO_INCREMENT PRIMARY KEY,
pseudo VARCHAR(50) NOT NULL,
message TEXT NOT NULL,
date_creation DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;Remarquez le DEFAULT CURRENT_TIMESTAMP : la date se remplit toute seule, vous n'avez pas à l'envoyer dans votre INSERT.
- La structure :
- Créer un projet avec un entry-point unique (
index.php) et une whitelist de 3 pages :home,connexion,admin. - Les pages sont dans le dossier
pages/, les éléments communs danscommon/, la connexion à la base dansutils/db.php.
- Créer un projet avec un entry-point unique (
Coup de pouce : l'entry-point
Vous l'avez déjà écrit au TP 3, et le code de référence est dans le support, section « La structure ». À adapter à vos 3 pages, sans oublier :
- Le
session_start()en toute première ligne (vous en aurez besoin pour l'espace admin). - L'
include('utils/db.php')avant le header, pour que$pdoexiste dans toutes vos pages. - La whitelist : un tableau +
in_array(). - Le cas d'une page non autorisée ou absente : retour sur
home.
- La page d'accueil (
home) :- Elle contient un formulaire POST avec un pseudo et un message.
- À la soumission, le message est enregistré en base dans la table
messages. - Si un champ est vide ou absent, afficher un message d'erreur (pas de warning PHP, et rien d'enregistré).
- Sous le formulaire, la page affiche l'ensemble des messages (pseudo, message et date) avec une boucle, du plus récent au plus ancien.
- Si aucun message n'est présent, afficher « Aucun message pour l'instant ».
Besoin d'aide pour l'enregistrement et la liste ?
Les deux formes dont vous avez besoin sont dans le support SQL. Souvenez-vous de la règle : des valeurs variables, donc requête préparée.
Pour enregistrer, la forme générale d'un ajout est INSERT INTO ma_table (colonne1, colonne2) VALUES (?, ?), puis un execute() avec un tableau contenant vos deux valeurs, dans l'ordre des ?.
Pour lister, aucune valeur variable, donc une requête classique suffit : un SELECT (voir « Obtenir des données ») suivi d'un fetchAll(). Pensez à l'ORDER BY pour le « du plus récent au plus ancien ».
Deux questions à vous poser : que renvoie fetchAll() exactement (quelle structure ?), et comment savoir simplement qu'il n'y a aucun message ?
- L'espace admin :
- La page
connexioncontient un formulaire de login (login + mot de passe, en dur pour cette évaluation, c'est autorisé). - Une fois connecté, l'utilisateur accède à la page
adminqui affiche le nombre de messages et la liste complète. - Non connecté, l'accès à
adminredirige versconnexion. - Un lien « Déconnexion » détruit la session de connexion.
- La page
Coup de pouce : protéger la page admin
Le mécanisme complet (connexion + protection) est décrit dans le support, section « espace d'administration ». Les trois ingrédients de la protection, à assembler en haut de la page à protéger :
- Un test sur la session (
isset()). - Une redirection (
header()). - Un
die()juste après (pourquoi est-il indispensable ? La réponse fera un bon commentaire dans votre code).
Et pour la déconnexion, regardez du côté de unset() (ou session_destroy()).
Un instant, réfléchissez
Les messages sont en base, l'état de connexion est en session. Pourquoi pas l'inverse ? Notez votre réponse en commentaire dans votre code : c'est exactement la distinction que nous avons faite depuis le TP 4, entre une donnée métier (qui doit survivre et être vue par tout le monde) et l'état d'un visiteur (qui ne concerne que lui, le temps de sa navigation).
Le challenge
Vous avez terminé ? Voici le défi bonus :
- Suppression : dans la page admin, ajouter un lien « Supprimer » à côté de chaque message. Le clic supprime définitivement le message de la base (un
DELETE, en requête préparée bien sûr, l'idvenant de l'URL). - Compteur : afficher sur la page d'accueil « Ce livre d'or contient X messages », en laissant la base faire le calcul avec un
COUNT(*)plutôt qu'en comptant les lignes en PHP.
Restitution
Le rendu se fait en deux temps :
- Poussez votre projet sur un dépôt Git sur le GitLab du lycée : https://gitlab.dombtsig.local, avec le
README.mdà la racine (contenu attendu : voir l'évaluation 1).- Ajoutez le script SQL de votre base à la racine du dépôt, sinon je ne pourrai pas faire tourner votre projet.
- Captures d'écran à inclure dans le README : la page d'accueil avec des messages, et la page admin connectée.
- Pensez à y indiquer le login et le mot de passe de l'espace admin, sinon la correction sera compliquée !
- Déposez le lien du dépôt dans Moodle (et vérifiez que j'y ai accès).
Un doute sur Git ? Initiation à Git, Utiliser GitLab, l'aide mémoire.
Bravo, vous avez terminé cette deuxième évaluation !