Construire une page dynamique
Le contenu d’une page Web peut être préparé à l’avance ou produit au moment où la page est demandée. Dans le premier cas, on parle généralement de contenu statique. Dans le second, la page est générée dynamiquement.
Tout au long du cours, nous rencontrerons différentes façons de construire une page web. Chaque stratégie répondra aux deux questions suivantes:
- où le contenu est-il produit : sur le serveur ou dans le navigateur ?
- quand est-il produit : avant la requête ou lorsque l’utilisateur demande la page ?
Mode de rendu d’une page Web
Section intitulée « Mode de rendu d’une page Web »Une page web statique, soit un fichier .html est envoyé tel quel par le serveur : ce que vous écrivez est exactement ce que le navigateur reçoit.
Lorsqu’un langage de programmation ou de scripting comme PHP (fichier .php) est utilisé pour décrire la page,
il est d’abord exécuté par le serveur pour produire le HTML qui sera envoyé par le serveur.
Le navigateur ne reçoit jamais le code PHP, seulement le HTML produit.
Rendement côté serveur vs côté client
Section intitulée « Rendement côté serveur vs côté client »Le type de rendu décrit plus haut est appelé rendu côté serveur : le serveur construit le HTML de la page avant de l’envoyer au navigateur. Cette approche est particulièrement utile lorsque le contenu doit être disponible dès la réponse du serveur, par exemple pour produire des pages à partir de données, centraliser la logique de présentation ou permettre une navigation classique où chaque adresse correspond à une page produite par le serveur. PHP fonctionne naturellement de cette façon : une requête arrive, le serveur exécute le programme PHP et retourne le HTML obtenu.
Le navigateur peut cependant lui aussi construire ou modifier une interface grâce à JavaScript. On parle alors de rendu côté client lorsque la construction d’une partie importante de l’interface se fait dans le navigateur après le chargement du JavaScript. Dans une application monopage (Single Page Application ou SPA), le serveur peut envoyer une structure HTML initiale relativement minimale, puis JavaScript prend en charge une grande partie de la construction de l’interface et de la navigation.
Suivez les trois moments du trajet, dans un mode puis dans l’autre : le début et la fin se ressemblent, c’est au milieu que tout se joue.
Section intitulée « Suivez les trois moments du trajet, dans un mode puis dans l’autre : le début et la fin se ressemblent, c’est au milieu que tout se joue. »<h1>Nos produits</h1> <p><?= count($products) ?> produits au catalogue.</p> <ul> <?php foreach ($products as $product): ?> <li> <?= $product['name'] ?> — <?= $product['price'] ?> $ <?php if ($product['stock'] > 0): ?> <strong>Disponible</strong> <?php else: ?> <strong>Rupture de stock</strong> <?php endif; ?> </li> <?php endforeach; ?> </ul>
Cycle de vie d’une page dynamique
Section intitulée « Cycle de vie d’une page dynamique »Chaque affichage d’une page PHP suit le même trajet, du clic jusqu’à l’écran.
-
Le navigateur envoie une requête HTTP vers une adresse.
-
Le serveur repère le fichier visé et exécute le code PHP qu’il contient.
-
PHP récupère ou prépare les données nécessaires : un tableau, un fichier, plus tard une base de données.
-
PHP produit le contenu HTML à partir de ces données.
-
Le serveur retourne la réponse HTTP, dont le corps est ce HTML.
-
Le navigateur interprète et affiche le HTML reçu.
- Navigateur vers Serveur + PHP : GET /produits.php
- Serveur + PHP : exécute produits.php
- Serveur + PHP vers Données : lecture des données (tableau, fichier ou base de données)
- Données vers Serveur + PHP : 2 produits
- Serveur + PHP : produit le HTML
- Serveur + PHP vers Navigateur : 200 · HTML produit
- Navigateur : interprète et affiche
VérificationVous modifiez une variable PHP dans produits.php. Sa valeur sera-t-elle encore là quand l'utilisateur cliquera vers contact.php ?
Non. Chaque requête déclenche une nouvelle exécution, indépendante de la précédente. Pour conserver une information d’une page à l’autre, il faut la transmettre explicitement (chaîne de requête, formulaire) ou la stocker (session, fichier, base de données).
Construction d’une page dynamique
Section intitulée « Construction d’une page dynamique »Voici une page de produits parfaitement ordinaire, écrite en HTML pur.
<h1>Nos produits</h1><ul> <li>Tire sur la neige — 6,25 $</li> <li>Sirop d'érable 540 ml — 14,50 $</li></ul>Elle a l’air simple, et elle l’est. Pourtant elle contient déjà les trois éléments d’une page dynamique, mêlés au point d’être indiscernables : les données, la logique qui détermine quoi afficher, et la présentation.
Les données sautent aux yeux : deux noms, deux prix. La présentation aussi : un titre, une liste. La logique, elle, est invisible — et c’est tout le problème. Le catalogue compte en réalité trois produits ; le beurre d’érable est en rupture et n’apparaît pas. La liste est triée par prix croissant. Le montant est écrit « 14,50 $ », avec la virgule et l’espace. Trois décisions ont donc bien été prises, mais hors du fichier : quelqu’un les a évaluées de tête, une fois, puis a écrit le résultat.
Construire une page dynamique, c’est ressortir ces éléments du HTML un par un, et les confier au serveur. Parcourez les quatre étapes : l’écran affiché reste rigoureusement le même, seule l’organisation change.
Tout est écrit à la main. Les trois produits du catalogue n'apparaissent pas : il en manque un, et l'ordre n'est pas celui du catalogue.
<h1>Nos produits</h1><ul> <li>Tire sur la neige — 6,25 $</li> <li>Sirop d'érable 540 ml — 14,50 $</li></ul>
Chaque extraction règle un problème et en révèle un autre. Sortir les données donne une source unique, mais la page continue de choisir ses produits à la main. Écrire la logique rend les règles lisibles, mais le HTML, resté figé, se met à contredire ce que la logique affirme. Ce n’est qu’à la dernière étape, quand la structure devient une boucle, que les trois pièces s’accordent.
Préparez d’abord, affichez ensuite. Tout ce qui calcule, filtre ou trie se place avant le premier caractère de HTML. La partie basse du fichier ne fait plus que parcourir et afficher : elle reste lisible même pour quelqu’un qui ne connaît pas PHP.
Composition de pages et création d’un site
Section intitulée « Composition de pages et création d’un site »Un site PHP est composé de plusieurs pages reliées par des liens HTML ordinaires. Naviguer vers une autre page déclenche une nouvelle requête : le cycle vu plus haut, répété.
<nav> <a href="index.php">Accueil</a> <a href="produits.php">Produits</a> <a href="contact.php">Contact</a></nav>Chacune de ces pages a besoin du même en-tête, de la même navigation, du même pied de page, souvent des mêmes données et des mêmes fonctions. Les recopier serait ingérable : la moindre retouche obligerait à ouvrir tous les fichiers. On les inclut plutôt.
Quatre cas d’usage
Section intitulée « Quatre cas d’usage »Lorsqu’il rencontre include ou require, PHP exécute le fichier demandé à cet endroit du programme.
Le HTML produit par ce fichier s’insère donc à cet endroit dans la réponse.
Mais on ne s’en sert pas pour la même chose, et c’est ce qu’on attend du fichier qui dicte le mécanisme à employer.
Le cadre commun. L’en-tête et le pied de page entourent le contenu de chaque page. Ils produisent du HTML, une fois par page.
<?php require __DIR__ . "/includes/header.php"; ?>
<main> <h2>Nos produits</h2></main>
<?php require __DIR__ . "/includes/footer.php"; ?>Le fragment répété. Un bloc qui revient — la carte d’un produit — est extrait puis inclus à chaque tour de boucle. Ici, la répétition est le but : surtout pas de _once.
<?php foreach ($afficher as $p): ?> <?php include __DIR__ . "/partials/product-card.php"; ?><?php endforeach; ?>Les déclarations. Un fichier de fonctions ou de classes produit rien à l’écran : il déclare. Le charger deux fois provoque une erreur fatale, puisqu’on ne peut pas redéclarer une fonction.
<?phprequire_once __DIR__ . "/lib/functions.php"; // formatPrix() déclarée ici, une seule foisLes données. Un fichier peut se contenter de return une valeur. C’est l’approche privilégiée pour les fichiers de configuration. On l’importe alors comme une expression, et la donnée cesse d’être mêlée à la page qui l’affiche — c’est l’extraction de l’étape 2, mais dans un fichier séparé.
<?phpreturn [ ["nom" => "Sirop d'érable 540 ml", "prix" => 14.50, "stock" => 8], ["nom" => "Beurre d'érable 250 g", "prix" => 9.95, "stock" => 0],];<?php$products = require __DIR__ . "/data/products.php";Choisir le bon mécanisme
Section intitulée « Choisir le bon mécanisme »Les quatre cas se distinguent par ce que le fichier produit, et cela suffit à trancher.
| Cas d’usage | Ce que le fichier produit | Mécanisme |
|---|---|---|
| En-tête, pied de page | du HTML, une fois par page | include ou require |
| Fragment répété | du HTML, à chaque tour de boucle | include, jamais _once |
| Fonctions, classes | rien à l’écran, des déclarations | require_once |
| Données, configuration | rien à l’écran, une valeur retournée | require avec affectation |
Reste à choisir entre include et require, qui ne diffèrent que par leur réaction à un fichier manquant.
| Mécanisme | Fichier introuvable |
|---|---|
include |
avertissement, le script continue |
require |
erreur fatale, le script s’arrête |
require dès que la page n’a aucun sens sans le fichier. Un en-tête absent, une configuration manquante, un fichier de fonctions introuvable : mieux vaut un arrêt net qu’une page à moitié construite, qui s’effondrera trois lignes plus loin avec un message incompréhensible.
Synthèse : une page assemblée
Section intitulée « Synthèse : une page assemblée »Les quatre cas se retrouvent dans une seule page. Sélectionnez un fichier pour isoler sa contribution au HTML final, ou suivez une ligne include pour aller voir le fichier qu’elle appelle.
include.<?php$titre = "Nos produits";?> <main> <h2><?php echo htmlspecialchars($titre); ?></h2> <?php foreach ($products as $p): ?> <?php endforeach; ?></main>
<header> <h1>L'Érablière dorée</h1> <nav>…</nav> </header>
<main> <h2>Nos produits</h2>
<article class="carte">
<h3>Sirop d'érable 540 ml</h3>
<p>14,50 $</p>
</article> <article class="carte">
<h3>Beurre d'érable 250 g</h3>
<p>9,95 $</p>
</article></main>
<footer> <p>© 2026 L'Érablière dorée</p> </footer>
Notez ce que produit chacun : data/products.php n’écrit rien mais fournit la matière ; header.php et footer.php posent le cadre ; product-card.php apparaît deux fois, une par produit ; et produits.php lui-même se réduit à trois variables et quatre inclusions.
Le trajet complet
Section intitulée « Le trajet complet »Composer un site, c’est séparer progressivement ses responsabilités. Le diagramme de séquence de la deuxième section suivait la requête entre les machines ; celui-ci suit les responsabilités à l’intérieur du serveur, de la demande jusqu’à l’écran.
Chaque étape a désormais son fichier, ou sa portion de fichier. C’est ce qui rend le site plus facile à comprendre, à modifier et à faire évoluer : on sait toujours où intervenir, et un changement reste local.
VérificationVous extrayez vos fonctions d'affichage dans lib/functions.php. Quel mécanisme d'inclusion, et pourquoi ?
require_once. require parce qu’une page privée de ses fonctions ne peut pas s’afficher : l’arrêt immédiat vaut mieux qu’une erreur obscure plus loin. Et _once parce qu’un fichier qui déclare des fonctions ne peut pas être chargé deux fois — PHP refuse toute redéclaration.
Réflexes et pièges
Section intitulée « Réflexes et pièges »- Le PHP reste sur le serveur : si vous voyez
<?phpdans le code source affiché par le navigateur, le fichier n’a pas été exécuté. - Les variables du script ne survivent pas à la requête. : les variables disparaissent à la fin du script. Transmettre ou stocker, jamais espérer.
- Préparer, puis afficher : la logique en haut du fichier, la présentation en bas.
- Échapper systématiquement :
htmlspecialchars(...)sur tout ce qui s’affiche, y compris dans les fragments réutilisés. _oncepour les déclarations,includesimple pour un fragment que l’on veut répéter.- Chemin d’URL ou chemin de fichier :
hrefpour le navigateur,include/requireavec__DIR__pour le serveur.
Récapitulatif
Section intitulée « Récapitulatif »- Une page PHP est exécutée sur le serveur ; le navigateur ne reçoit que le HTML produit. Le rendu côté client, lui, construit l’interface en JavaScript après réception.
- Le cycle d’une page dynamique va de la requête HTTP à l’affichage, en passant par l’exécution du fichier, la préparation des données et la production du HTML.
- Une page dynamique combine données, logique et présentation — dans cet ordre, de préférence.
- Un site s’assemble à partir de pages reliées par des liens, de parties incluses (
header.php,footer.php,partials/) et de fichiers de données importés parrequire. requireconvient aux fichiers indispensables,require_onceaux fichiers qui déclarent des fonctions ou des classes, etincludeaux fragments de présentation que l’on veut pouvoir répéter.- Un lien utilise un chemin d’URL interprété par le navigateur, tandis que
includeetrequireutilisent des chemins de fichiers interprétés sur le serveur.__DIR__permet d’ancrer ces chemins sur le fichier courant.
Quiz. Pourquoi le navigateur ne reçoit-il jamais de code PHP ?
Quiz. Que se passe-t-il exactement quand l'utilisateur clique sur <a href='produits.php'> ?
Quiz. À quoi sert __DIR__ dans require __DIR__ . '/data/products.php' ?