Exercices — Navigation et composition
Niveau 1 — Découper une page : fragments, include et require
Section intitulée « Niveau 1 — Découper une page : fragments, include et require »Dans la construction d’un site ou une application web, le réflexe de base à avoir est : repérer ce qui se répète, le sortir dans un fichier (un fragment), et l’insérer là où il faut avec include ou require.
Exercice 1.1 : Repérer les fragments et le contenu propre
Section intitulée « Exercice 1.1 : Repérer les fragments et le contenu propre »Voici deux pages d’un même site. Repère ce qui est identique sur les deux (à extraire dans des fragments) et ce qui est propre à chaque page.
Page accueil.php
Section intitulée « Page accueil.php »<!doctype html><html lang="fr"><head><title>Accueil — Érablière</title></head><body> <nav><a href="accueil.php">Accueil</a> · <a href="contact.php">Contact</a></nav> <main> <h1>Bienvenue à l'Érablière dorée</h1> <p>Nos produits d'érable, directement de la cabane.</p> </main> <footer>© 2025 L'Érablière dorée</footer></body></html>Page contact.php
Section intitulée « Page contact.php »<!doctype html><html lang="fr"><head><title>Contact — Érablière</title></head><body> <nav><a href="accueil.php">Accueil</a> · <a href="contact.php">Contact</a></nav> <main> <h1>Nous joindre</h1> <p>Téléphone : 1 800 ÉRABLE.</p> </main> <footer>© 2025 L'Érablière dorée</footer></body></html>Vérification Indice
Lis les deux pages côte à côte. Ce qui est rigoureusement identique peut vivre dans un seul fichier partagé. Ce qui change d’une page à l’autre reste propre à la page.
Vérification Solution
Identique → deux fragments.
entete.php: L’en-tête, du<!doctype html>jusqu’à la fin du<nav>.pied.php: Le<footer>et la fermeture (</body></html>).
Propre à chaque page → le contenu.
- Seul le
<main>change et c’est tout ce que chaque fichier de page (accueil.php,contact.php) doit garder.
Le <title> diffère lui aussi (« Accueil — … » contre « Contact — … »).
On peut résoudre ça en passant le titre à l’en-tête par une variable.
Exercice 1.2 : Insérer un fragment avec include
Section intitulée « Exercice 1.2 : Insérer un fragment avec include »Les fragments entete.php et pied.php existent déjà (ci-dessous).
Écris accueil.php pour qu’il les insère autour de son contenu, sans recopier le HTML commun.
Fragment entete.php
Section intitulée « Fragment entete.php »<!doctype html><html lang="fr"><head><title>L'Érablière dorée</title></head><body> <nav><a href="accueil.php">Accueil</a> · <a href="contact.php">Contact</a></nav>Fragment pied.php
Section intitulée « Fragment pied.php » <footer>© 2025 L'Érablière dorée</footer></body></html>Vérification Indice
include 'fichier.php'; insère le contenu du fichier à cet endroit, comme un copier-coller exécuté. Place l’include de l’en-tête avant ton contenu, et celui du pied après.
Vérification Solution
<?php include 'entete.php'; ?>
<main> <h1>Bienvenue à l'Érablière dorée</h1> <p>Nos produits d'érable, directement de la cabane.</p></main>
<?php include 'pied.php'; ?>Exercice 1.3 : Passer le titre au fragment
Section intitulée « Exercice 1.3 : Passer le titre au fragment »Le <title> change d’une page à l’autre, mais l’en-tête est partagé. Un fichier inclus voit les variables définies avant son include. Voici entete.php, qui attend désormais une variable $titre :
<!doctype html><html lang="fr"><head><title><?= htmlspecialchars($titre) ?></title></head><body> <nav><a href="accueil.php">Accueil</a> · <a href="contact.php">Contact</a></nav>Écris le début de accueil.php pour que le titre affiché soit « Accueil — Érablière ».
Vérification Indice
Définis $titre avant d’inclure entete.php. L’include n’a pas de portée séparée : il partage les variables de la page qui l’inclut.
Vérification Solution
<?php $titre = 'Accueil — Érablière'; ?><?php include 'entete.php'; ?>
<main> <h1>Bienvenue à l'Érablière dorée</h1></main>
<?php include 'pied.php'; ?>Niveau 2 — Naviguer entre les pages
Section intitulée « Niveau 2 — Naviguer entre les pages »Les pages assemblées, reste à les relier et à réagir à ce que l’URL demande.
Exercice 2.1 : Relier les pages
Section intitulée « Exercice 2.1 : Relier les pages »Dans entete.php, la barre de navigation relie les pages du site.
Écris le <nav> qui mène à l’accueil, aux produits et au contact (fichiers accueil.php, produits.php, contact.php).
Vérification Indice
Un lien interne, c’est <a href="produits.php">Produits</a>. Le chemin est relatif au dossier de la page courante.
Vérification Solution
<nav> <a href="accueil.php">Accueil</a> <a href="produits.php">Produits</a> <a href="contact.php">Contact</a></nav>Exercice 2.2 : Lire la page demandée dans l’URL
Section intitulée « Exercice 2.2 : Lire la page demandée dans l’URL »Une URL comme produits.php?categorie=sirop transporte une donnée après le ?. PHP la dépose dans la superglobale $_GET.
Récupère la catégorie demandée, ou 'tous' si aucune n’est précisée.
// produits.php?categorie=sirop → $categorie vaut "sirop"// produits.php → $categorie vaut "tous"Vérification Indice
$_GET['categorie'] contient la valeur écrite après categorie=. Au premier affichage, sans paramètre, cette clé n’existe pas : ?? fournit alors la valeur par défaut.
Vérification Solution
<?php$categorie = $_GET['categorie'] ?? 'tous';Exercice 2.3 : Marquer la page active
Section intitulée « Exercice 2.3 : Marquer la page active »Pour aider le visiteur à se repérer, la page courante doit se distinguer dans le menu. La page courante est connue dans $pageActive. Ajoute la classe actif au seul lien correspondant.
// Si $pageActive vaut 'produits', seul le lien Produits reçoit class="actif".Vérification Indice
Pour chaque lien, compare sa cible à $pageActive. Si elles correspondent, écris class="actif", sinon rien. Un opérateur ternaire (?:) tient sur une ligne, à l’intérieur de l’attribut.
Vérification Solution
<nav> <a href="accueil.php" class="<?= $pageActive === 'accueil' ? 'actif' : '' ?>">Accueil</a> <a href="produits.php" class="<?= $pageActive === 'produits' ? 'actif' : '' ?>">Produits</a> <a href="contact.php" class="<?= $pageActive === 'contact' ? 'actif' : '' ?>">Contact</a></nav>Niveau 3 — Automatiser la composition avec des fonctions
Section intitulée « Niveau 3 — Automatiser la composition avec des fonctions »Mêmes idées, mais cette fois on remplace les fragments par des fonctions qui retournent du HTML : plus souples, paramétrables et testables.
Exercice 3.1 : L’en-tête et le pied en fonctions
Section intitulée « Exercice 3.1 : L’en-tête et le pied en fonctions »Transforme tes fragments en fonctions : entete($titre) ouvre la page avec un titre, pied() la referme. (C’est la version « fonction » des exercices 1.2 et 1.4.)
Signature : entete(string $titre): string et pied(): string
echo entete('Accueil');// <!doctype html><html lang="fr"><head><title>Accueil</title></head><body>
echo pied();// </body></html>Vérification Indice
Chaque fonction retourne un morceau de HTML. entete reçoit le titre à insérer dans <title> ; échappe-le avec htmlspecialchars(). pied n’a besoin d’aucun paramètre.
Vérification Solution
function entete(string $titre): string{ $titre = htmlspecialchars($titre); return '<!doctype html><html lang="fr"><head><title>' . $titre . '</title></head><body>';}
function pied(): string{ return '</body></html>';}Exercice 3.2 : Charger des données depuis un fichier PHP
Section intitulée « Exercice 3.2 : Charger des données depuis un fichier PHP »Pour séparer les données de l’affichage, on les range dans un fichier PHP à part.
Un fichier qui se termine par return renvoie une valeur, et require la récupère.
Voici le fichier de données ; dans produits.php, charge ce tableau dans $produits, puis affiche la liste.
<?phpreturn [ ["nom" => "Sirop d'érable 540 ml", "prix" => 14.50], ["nom" => "Beurre d'érable 250 g", "prix" => 9.95], ["nom" => "Tire sur la neige", "prix" => 6.00],];Vérification Indice
Un fichier qui fait return [...] renvoie cette valeur à qui l’inclut. On la capture donc dans une variable : $donnees = require 'fichier.php';. Ensuite, $produits est un tableau ordinaire — count, foreach, etc.
Vérification Solution
<?php$produits = require 'data/produits.php';
echo count($produits) . ' produits au catalogue :';
foreach ($produits as $p) { $prix = number_format($p['prix'], 2, ',', ' '); echo '<p>' . htmlspecialchars($p['nom']) . ' — ' . $prix . ' $</p>';}// → 3 produits au catalogue : Sirop d'érable 540 ml — 14,50 $ ...Exercice 3.3 : Un menu qui se génère
Section intitulée « Exercice 3.3 : Un menu qui se génère »Dernière pièce : produire la barre de navigation par une fonction, à partir d’une liste de pages (url => libellé),
en mettant en évidence la page courante.
C’est l’extension de l’exercice 2.3.
Signature : menu(array $pages, string $courant): string
$pages = ['accueil' => 'Accueil', 'contact' => 'Contact'];menu($pages, 'contact');// <nav><a href="accueil">Accueil</a><a href="contact" class="actif">Contact</a></nav>Vérification Indice
Parcours le tableau avec foreach ($pages as $url => $libelle). Pour chaque entrée, ajoute class="actif" si $url === $courant. Accumule les liens dans une chaîne (.=), puis enveloppe le tout dans <nav>...</nav>. Pense à htmlspecialchars() sur le libellé.
Vérification Solution
function menu(array $pages, string $courant): string{ $liens = ''; foreach ($pages as $url => $libelle) { $libelle = htmlspecialchars($libelle); $classe = $url === $courant ? ' class="actif"' : ''; $liens .= '<a href="' . $url . '"' . $classe . '>' . $libelle . '</a>'; } return '<nav>' . $liens . '</nav>';}