322 votes

Quelle est l'utilité de ob_start() en php ?

Est ob_start() utilisé pour output buffering pour que les en-têtes soient mis en mémoire tampon et ne soient pas envoyés au navigateur ? Est-ce que j'ai bien compris ? Si non, pourquoi devrions-nous utiliser ob_start() ?

519voto

Riley Dutton Points 2041

Pensez à ob_start() comme disant "Commencez à vous souvenir de tout ce qui devrait normalement être sorti, mais n'en faites pas encore quelque chose".

Par exemple :

ob_start();
echo("Hello there!"); //would normally get printed to the screen/output to browser
$output = ob_get_contents();
ob_end_clean();

Il y a deux autres fonctions avec lesquelles vous l'associez généralement : ob_get_contents() qui vous donne essentiellement tout ce qui a été "sauvegardé" dans le tampon depuis qu'il a été activé avec la fonction ob_start() y luego ob_end_clean() o ob_flush() qui soit arrête de sauvegarder et jette ce qui a été sauvegardé, soit arrête de sauvegarder et sort tout en une fois, respectivement.

60 votes

Excellente explication. J'irais même plus loin en remplaçant ob_get_contents() con ob_get_clean() et retirer ob_end_clean() depuis ob_get_clean() remplit essentiellement les deux fonctions. Référence : php.net/manual/fr/function.ob-get-clean.php (PHP 4 >= 4.3.0, PHP 5)

1 votes

Je suppose que la mise en tampon de la sortie doit être activée dans le fichier .ini afin d'appeler ob_start(); Est-ce correct ? Que se passe-t-il s'il n'est pas activé ?

5 votes

@Riley Dutton Vous ne dites pas pourquoi la fonction ob_start() est utilisée.

176voto

JD Isaacks Points 14540

Je l'utilise pour pouvoir sortir de PHP avec beaucoup de HTML mais sans le rendre. Cela m'évite de le stocker sous forme de chaîne, ce qui désactive le code couleur de l'IDE.

<?php
ob_start();
?>
<div>
    <span>text</span>
    <a href="#">link</a>
</div>
<?php
$content = ob_get_clean();
?>

Au lieu de :

<?php
$content = '<div>
    <span>text</span>
    <a href="#">link</a>
</div>';
?>

1 votes

Peut-on l'utiliser comme un moyen d'avoir plusieurs pages html dans un PHP et de les appeler via GET ?

1 votes

Je suppose, mais ça ne semble pas être une bonne idée. Il serait préférable de les charger à partir de modèles distincts.

1 votes

Notez que cette technique utilise ob_get_clean() pas ob_end_clean()

31voto

Craige Points 1368

Vous avez inversé les choses. ob_start ne met pas en mémoire tampon les en-têtes, il met en mémoire tampon le contenu. En utilisant ob_start vous permet de conserver le contenu dans une mémoire tampon côté serveur jusqu'à ce que vous soyez prêt à l'afficher.

Ceci est généralement utilisé pour que les pages puissent envoyer des en-têtes "après" avoir déjà "envoyé" du contenu (c'est-à-dire en décidant de rediriger à mi-chemin du rendu d'une page).

3 votes

+1 Moi aussi j'ai été confus quant à l'utilisation réelle de la fonction. Votre réponse concernant son utilisation pendant la "redirection" m'a rappelé toutes les fois où j'ai eu l'erreur "Headers already sent". Merci

12voto

dsdsdsdsd Points 545

Ceci est pour clarifier davantage Réponse de JD Isaaks ...

Le problème que l'on rencontre souvent est que l'on utilise php pour produire du html à partir de plusieurs sources php différentes, et ces sources sont souvent, pour une raison quelconque, produites de différentes manières.

Parfois, vous disposez d'un contenu html littéral que vous souhaitez transmettre directement au navigateur. Dans d'autres cas, le contenu est créé de manière dynamique (côté serveur).

Le contenu dynamique sera toujours ( ?) une chaîne. Maintenant, vous devez combiner ce html dynamique stringifié avec tout html littéral, direct-to-display ... dans une structure de nœuds html significative.

Cela oblige généralement le développeur à envelopper tout ce contenu d'affichage direct dans une chaîne de caractères (comme JD Isaak en parlait) afin qu'il puisse être correctement livré/inséré en conjonction avec le html dynamique... même si vous ne voulez pas vraiment qu'il soit enveloppé.

Mais en utilisant les méthodes ob_##, vous pouvez éviter ce désordre dans les chaînes de caractères. Le contenu littéral est, à la place, sorti dans le tampon. Puis, en une seule étape, le contenu entier du tampon (tout le html littéral) est concaténé dans votre chaîne html dynamique.

(Mon exemple montre du html littéral sorti dans le tampon, qui est ensuite ajouté à une chaîne html ... regardez aussi l'exemple de JD Isaaks pour voir le string-wrapping-of-html).

<?php // parent.php

//---------------------------------
$lvs_html  = "" ;

$lvs_html .= "<div>html</div>" ;
$lvs_html .= gf_component_assembler__without_ob( ) ;
$lvs_html .= "<div>more html</div>" ;

$lvs_html .= "----<br/>" ;

$lvs_html .= "<div>html</div>" ;
$lvs_html .= gf_component_assembler__with_ob( ) ;
$lvs_html .= "<div>more html</div>" ;

echo $lvs_html ;    
//    02 - component contents
//    html
//    01 - component header
//    03 - component footer
//    more html
//    ----
//    html
//    01 - component header
//    02 - component contents
//    03 - component footer
//    more html 

//---------------------------------
function gf_component_assembler__without_ob( ) 
  { 
    $lvs_html  = "<div>01 - component header</div>" ; // <table ><tr>" ;
    include( "component_contents.php" ) ;
    $lvs_html .= "<div>03 - component footer</div>" ; // </tr></table>" ;

    return $lvs_html ;
  } ;

//---------------------------------
function gf_component_assembler__with_ob( ) 
  { 
    $lvs_html  = "<div>01 - component header</div>" ; // <table ><tr>" ;

        ob_start();
        include( "component_contents.php" ) ;
    $lvs_html .= ob_get_clean();

    $lvs_html .= "<div>03 - component footer</div>" ; // </tr></table>" ;

    return $lvs_html ;
  } ;

//---------------------------------
?>

<!-- component_contents.php -->
  <div>
    02 - component contents
  </div>

4voto

elusive Points 14184

Cette fonction n'est pas seulement pour les en-têtes. Vous pouvez faire beaucoup de choses intéressantes avec elle. Exemple : Vous pouvez diviser votre page en sections et l'utiliser comme ceci :

$someTemplate->selectSection('header');
echo 'This is the header.';

$someTemplate->selectSection('content');
echo 'This is some content.';

Vous pouvez capturer la sortie qui est générée ici et l'ajouter à deux endroits totalement différents dans votre mise en page.

0 votes

Cela ressemble un peu à ce que je recherche. Je dois rendre des éléments aux "sections" (pensez aux fichiers JS et CSS), mais je dois pouvoir les appeler dans le modèle (qui est chargé plus tard que l'en-tête)... Ainsi, si j'appelle "$this->addcss('specificCSStoThisView') ;", je veux qu'il soit rendu entre les balises <head>. Je n'arrive pas à trouver cela sur Google. Pourriez-vous peut-être m'indiquer la bonne direction ? Je vous remercie !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X