Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Oui, je sais : c'est assez laid à dire, "tamporisation de sortie". Sachez que le terme
bufferisation de sortie signifie exactement la même chose, et c'est probablement celui que vous verrez le plus souvent. Par contre, j'utilise le premier car il est plus français.
Lorsque vous chargez un script PHP pour un site web, il retourne des données au navigateur. Généralement, vous ne vous préoccupez que de retourner du HTML, parfois quelques cookies ou d'autres informations d'en-tête avec
header(). Donc, selon ce que vous savez jusqu'à maintenant, si je fais :
Code : PHP
ça retourne au navigateur du visiteur le mot "Salut !", logique. Si je veux faire une redirection en PHP en modifiant les en-têtes HTTP, et que je procède ainsi :
Code : PHP1
2
3
4 | <?php
echo 'Salut !';
header('Location: page.php');
?>
|
vous vous en doutez, on obtiendra l'erreur suivante :
Citation : erreurWarning: Cannot modify header information - headers already sent by (output started at c:\www\lol.php:2) in c:\www\lol.php on line 3
Ceci est
normal : on ne peut pas dire au navigateur qu'on redirige vers une autre page alors qu'on a déjà commencé à lui donner la première. C'est comme si au restaurant, vous disiez au serveur que vous changiez de commande alors que le cuisinier a déjà commencé à préparer votre plat !

Maintenant, que dites-vous de ce code :
Code : PHP1
2
3
4
5
6 | <?php
$output = '';
$output .= 'Salut !';
header('Location: page.php');
echo $output;
?>
|
Ça fait une erreur ? Évidemment, ça n'en fait pas. Dans un premier temps, on initialise une variable
$output, on lui assigne la valeur d'une chaîne de caractères vide. Jusqu'ici, on n'a fait aucun retour de HTML au navigateur. Ensuite, on ajoute à cette variable la valeur "Salut !". Si vous ne comprenez pas la signification du
.=, je vous suggère de revoir le chapitre du cours de M@teo21 sur
la concaténation.

Encore une fois, on n'a rien retourné au navigateur. On fait notre redirection avec
header(), puis on affiche la valeur de
$output. Donc, aucune erreur, notre code a été affiché après la redirection !
Mine de rien, vous avez maintenant le principe de la tamporisation de sortie : on stocke tout ce qu'on veut afficher dans une variable, et
à la fin (et seulement à la fin, sinon on perd tout l'intérêt), on affiche le contenu.
Initialiser et vider le tampon de sortie
Maintenant qu'on sait ce que c'est, on va voir comment ça marche !

PHP nous offre toute une gamme de fonctions pour la tamporisation de sortie ; nous n'en utiliserons que deux, car ce sont les deux principales. Ces fonctions, ce sont
ob_start() et
ob_end_flush().
- ob_start() : cette fonction initialise le tampon de sortie, c'est-à-dire que tout ce que vous affichez après son appel (avec echo et print) est mis dans le tampon au lieu d'être retourné au navigateur.
- ob_end_flush() : lors de l'appel de cette fonction, tout le contenu de votre tampon est retourné au navigateur et donc, affiché.
Le principe est simple, on va appeler
ob_start() au tout début, et
ob_end_flush() à la toute fin. Ce que vous afficherez entre les deux avec
print et
echo (ou avec
?>...<?php) sera stocké dans le tampon (
buffer), puis affiché à la fin. Exemple :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | <?php
ob_start(); /* On initialise le tampon */
/* Trois façons d'ajouter du texte au buffer */
echo 'Blablabla voici du texte qui sera mis dans dans le buffer';
?>
Encore du texte qui sera mis dans le buffer !
<?php
print 'OMG, encore du texte à mettre dans le buffer ! Il va déborder !?';
$now = time();
$end = $now + 600;
setcookie('debut', $now, $end);
ob_end_flush(); /* On vide le tampon et on retourne le contenu au client */
?>
|
Récupérer le contenu du buffer (tampon)
À tout moment pendant l'exécution de votre script (entre
ob_start() et
ob_end_flush()), vous pouvez récupérer le contenu du buffer avec la fonction
ob_get_contents(). Ça peut être pratique parfois (mais rarement primordial), à vous de voir là où ça pourrait vous servir. Exemple avec
ob_get_contents :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | <?php
ob_start(); /* On initialise le tampon */
/* Trois façons d'ajouter du texte au buffer */
echo 'Blablabla voici du texte qui sera mis dans dans le buffer';
?>
Encore du texte qui sera mis dans le buffer !
<?php
print 'OMG, encore du texte à mettre dans le buffer ! Il va déborder !?';
$now = time();
$end = $now + 600;
setcookie('debut', $now, $end);
$contents = ob_get_contents(); // Que vaut $contents ??
ob_end_flush(); /* On vide le tampon et on retourne le contenu au client */
?>
|
Vous vous en doutez,
$contents vaut alors :
Citation : $contentsBlablabla voici du texte qui sera mis dans dans le bufferEncore du texte qui sera mis dans le buffer !OMG, encore du texte à mettre dans le buffer ! Il va déborder !?
Autres fonctions utiles
Voici une liste d'autres fonctions utiles à connaître, vous trouverez des détails plus précis dans la documentation de PHP :
- ob_flush() : affiche le contenu du tampon de sortie (contrairement à ob_end_flush, cela ne détruit pas votre buffer, ça ne fait que le retourner au navigateur, vous pouvez donc continuer à l'utiliser après).
- ob_clean() : cette fonction réinitialise le tampon de sortie, c'est-à-dire qu'elle le remet à zéro sans le retourner au navigateur : vous perdez tout ce que vous avez affiché avant son appel.
Si vous avez trouvé jusqu'ici ce que vous désiriez, et que vous ne désirez pas pousser la machine plus loin (ça arrive

), cette partie n'est pas pour vous. Ici on verra comment utiliser les paramètres
facultatifs de la fonction
ob_start(). J'insiste sur le fait qu'ils sont facultatifs, ainsi, le code ci-dessous initialise bel et bien le tampon de sortie :
Code : PHP
Un callback, qu'est-ce que c'est ?
Un
callback est l'appel d'une fonction définie par l'utilisateur, ou une fonction native de PHP à partir des paramètres d'une autre. Voyez
le site de PHP à ce sujet. La fonction
call_user_func() nous permet justement d'appeler une fonction en donnant son nom en premier argument. Les paramètres qui suivent le nom correspondront respectivement aux paramètres de la fonction que vous appelez. Testez le code ci-dessous pour vous en convaincre :
Code : PHP1
2
3
4
5
6
7 | <?php
function AfficherNom($nom) {
echo('Ton nom est ' . $nom);
return(true);
}
call_user_func('AfficherNom', 'Alex');
?>
|
En tamporisation de sortie, on peut donner un callback en paramètre à
ob_start(). La fonction donnée en callback sera appelée au retour du buffer au navigateur, avec
ob_end_flush() par exemple, et le contenu du tampon sera remplacé par ce que retourne la fonction de callback. Supposons que nous désirons impérativement censurer les mots suivants de tout notre site :
patate, nain, chose. Il existe plusieurs solutions, mais nous pouvons le faire avec un callback :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | <?php
function Censurer($buffer) {
//Ici c'est notre fonction qui sera appelé avec ob_end_flush();
$buffer = str_replace(array('patate', 'nain', 'chose'), '<span style="color: red;"> [Censuré] </span>', $buffer);
return $buffer;
}
//On initialise le buffer
ob_start('Censurer');
//... le contenu de notre page
echo "J'aime bien les nains, surtout ceux qui mangent des patates et qui aiment faire des choses.";
/*
Ici, la fonction ob_end_flush() va être appelé,
ce qui provoquera le retour du tampon au navigateur.
Mais avant, notre fonction de callback sera
automatiquement appelée pour appliquer la censure.
*/
ob_end_flush();
?>
|
Citation : RésultatJ'aime bien les [Censuré] s, surtout ceux qui mangent des [Censuré] s et qui aiment faire des [Censuré] s.
Encore une fois, c'est du facile tout ça.