ob_start

Résumé Support Quiz

Les fonctions de bufferisation de sortie permettent de mieux contrôler ce qui est affiché par PHP. Le nom peut paraître compliqué, mais le principe est simple : au lieu d'afficher directement le contenu, on le garde temporairement en mémoire pour le récupérer plus tard. C'est particulièrement utile lorsqu'on organise une application avec un routeur, des templates et un layout commun.

Le problème avec le layout

Dans l'organisation précédente, on chargeait généralement le header avant le template, puis le footer après.

require '../elements/header.php'; require '../templates/contact.php'; require '../elements/footer.php';

Cette approche fonctionne, mais elle a une limite : le header est inclus avant le template. Si on veut définir le titre ou la description de la page depuis le template, c'est trop tard, car le header a déjà été affiché.

On aimerait pouvoir écrire dans templates/contact.php :

<?php $pageTitle = 'Nous contacter'; $pageDescription = 'Nous contacter grâce à ce super formulaire de contact'; ?> <h1>Nous contacter</h1>

Puis utiliser ces variables dans un fichier de layout.

<title><?= $pageTitle ?? 'Mon site' ?></title> <meta name="description" content="<?= $pageDescription ?? '' ?>">

Pour que cela fonctionne, il faut d'abord exécuter le template, récupérer son contenu dans une variable, puis seulement ensuite charger le layout.

Le rôle de la bufferisation

Quand on utilise require, PHP affiche directement le contenu généré par le fichier inclus. Les fonctions de bufferisation permettent de changer ce comportement. On va créer une mémoire tampon : tout ce qui devrait être affiché est gardé en mémoire. On peut ensuite choisir de récupérer ce contenu, de l'afficher ou de le supprimer.

ob_start(); echo 'Salut';

À partir de l'appel à ob_start(), le contenu n'est plus envoyé directement en sortie. Il est stocké dans un tampon.

Supprimer ou afficher le tampon

Plusieurs fonctions permettent ensuite d'agir sur ce tampon.

ob_start(); echo 'Salut'; ob_clean(); // Supprime ce qui a été gardé en mémoire

Avec ob_flush(), on envoie le contenu du tampon vers la sortie.

ob_start(); echo 'Salut'; ob_flush(); // Affiche ce qui est en mémoire avant de nettoyer

Récupérer le contenu avec ob_get_clean()

La fonction la plus intéressante dans notre cas est ob_get_clean(). Elle permet de récupérer le contenu courant du tampon, puis de l'effacer.

ob_start(); echo 'Salut'; $content = ob_get_clean(); var_dump($content);

Ici, $content contient la chaîne Salut. Le contenu n'a pas été affiché directement, il a été capturé dans une variable.

Cela fonctionne aussi avec du HTML écrit en dehors des balises PHP.

<?php ob_start(); ?> <h1>Salut</h1> <p>Bienvenue sur mon site</p> <?php $content = ob_get_clean(); ?>

Le tampon garde tout ce qui aurait dû être affiché, qu'il s'agisse d'un echo ou de HTML classique.

Il existe une limite à la quantité de contenu que l'on peut garder en mémoire, mais pour capturer le HTML d'une page classique, cela reste largement suffisant.

Appliquer la bufferisation aux templates

Dans notre application, on peut utiliser cette logique pour capturer le rendu du template.

ob_start(); require '../templates/contact.php'; $pageContent = ob_get_clean(); require '../elements/layout.php';

Le fichier contact.php peut définir des variables comme $pageTitle ou $pageDescription, puis générer le HTML de la page. Tout ce HTML sera capturé dans $pageContent.

Ensuite, le layout peut afficher les métadonnées et insérer le contenu au bon endroit.

<!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <title><?= $pageTitle ?? 'Mon site' ?></title> <meta name="description" content="<?= $pageDescription ?? '' ?>"> </head> <body> <div class="container"> <?= $pageContent ?> </div> </body> </html>

Avec cette organisation, on n'a plus besoin de séparer header.php et footer.php. On peut utiliser un seul fichier layout.php, qui représente la structure complète de la page.

Ajouter du contenu spécifique à une page

Le même principe peut être utilisé pour définir du contenu additionnel dans une page, par exemple du JavaScript spécifique.

Dans le layout, on peut prévoir une variable facultative.

<?= $pageJavaScript ?? '' ?>

Puis, dans un template, on peut capturer un script avec un second niveau de bufferisation.

<?php ob_start(); ?> <script> alert('Salut'); </script> <?php $pageJavaScript = ob_get_clean(); ?>

Les tampons peuvent être imbriqués. Si un ob_start() est lancé dans un template alors qu'un autre tampon est déjà actif autour du template, ob_get_clean() récupère seulement le dernier niveau ouvert. Cela permet de capturer proprement différentes parties d'une page sans les afficher immédiatement.

Séparer les routes de la logique principale

Une fois cette structure en place, le fichier public/index.php peut rester très simple. Il contient la logique générale : charger l'autoloader, initialiser le routeur, trouver la route, capturer le template et charger le layout.

Pour éviter de modifier constamment ce fichier, on peut déplacer la déclaration des routes dans un fichier dédié.

config/ routes.php public/ index.php templates/ contact.php home.php elements/ layout.php

Dans public/index.php, on charge simplement la configuration.

require '../config/routes.php';

L'intérêt est de séparer la logique principale de l'application et la déclaration des routes. On ne touche presque plus à index.php, et on ajoute ou modifie les pages depuis config/routes.php.

À retenir

La bufferisation de sortie permet de capturer ce que PHP aurait normalement affiché directement. Avec ob_start() et ob_get_clean(), on peut récupérer le rendu d'un template dans une variable, puis l'insérer dans un layout.

Cette approche permet notamment de :

  • définir le titre et la description depuis le template.
  • utiliser un layout unique au lieu d'un header et d'un footer séparés.
  • capturer du contenu spécifique à une page, comme du JavaScript.
  • mieux séparer les templates, les routes et la logique principale.

Ressources