web-dev-qa-db-fra.com

Quelle est l'utilisation de ob_start () en php?

ob_start() est-il utilisé pour output buffering afin que les en-têtes soient mis en mémoire tampon et non envoyés au navigateur? Est-ce que j'ai un sens ici? Sinon, pourquoi devrions-nous utiliser ob_start()?

244
Aditya Shukla

Pensez à ob_start() comme disant "Commencez par vous souvenir de tout ce qui serait normalement affiché, mais ne faites pas encore tout à fait avec."

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 associe généralement deux autres fonctions: ob_get_contents(), ce qui vous donne ce qui a été "sauvegardé" dans le tampon depuis l'activation de ob_start(), puis ob_end_clean() ou ob_flush(), qui arrête d'enregistrer des éléments et annule ceux qui ont été enregistrés. , ou arrête de sauvegarder et sort le tout en même temps, respectivement.

390
Riley Dutton

J'utilise ceci pour pouvoir sortir de PHP avec beaucoup de HTML sans le rendre. Cela me évite de le stocker sous forme de chaîne qui désactive le codage couleur 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>';
?>
131
JD Isaacks

La réponse acceptée ici décrit ce que ob_start() fait - pas pourquoi il est utilisé (quelle était la question posée).

Comme indiqué ailleurs, ob_start() crée un tampon dans lequel le résultat est écrit. 

Mais personne n'a mentionné qu'il est possible d'empiler plusieurs tampons dans PHP. Voir ob_get_level ().

Quant au pourquoi ....

  1. L'envoi de HTML au navigateur par gros morceaux offre un avantage en termes de performance grâce à une surcharge du réseau.

  2. Transmettre les données hors de PHP en morceaux plus volumineux améliore les performances et la capacité en réduisant le nombre de changements de contexte nécessaires.

  3. Le fait de transmettre des morceaux de données plus importants à mod_gzip/mod_deflate offre un avantage en termes de performances, dans la mesure où la compression peut être plus efficace.

  4. la mise en mémoire tampon de la sortie signifie que vous pouvez toujours manipuler les en-têtes HTTP plus tard dans le code

  5. explicitement flushing le tampon après la sortie de [head] .... [/ head] peut permettre au navigateur de commencer à marshaler d'autres ressources pour la page avant la fin du flux HTML.

  6. La capture de la sortie dans une mémoire tampon signifie qu’elle peut être redirigée vers d’autres fonctions, telles que la messagerie électronique, ou copiée dans un fichier en tant que représentation mise en cache du contenu.

75
symcbean

Vous l'avez à l'envers. ob_start ne met pas les en-têtes en mémoire tampon, il met le contenu en mémoire tampon. Utiliser 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 couramment utilisé pour que les pages puissent envoyer des en-têtes «après» avoir déjà envoyé du contenu (c'est-à-dire, décider de rediriger vers le milieu du rendu d'une page).

28
Craige

Je préfère:

ob_start();
echo("Hello there!");
$output = ob_get_clean(); //Get current buffer contents and delete current output buffer
11
hawx

c'est pour clarifier davantage Réponse de JD Isaaks ... 

Le problème que vous rencontrez souvent est que vous utilisez php pour générer du HTML à partir de différentes sources php. Ces sources produisent souvent, pour une raison quelconque, une sortie de différentes manières. 

Parfois, vous avez un contenu HTML littéral que vous souhaitez envoyer directement au navigateur; d'autres fois, la sortie est créée dynamiquement (côté serveur). 

Le contenu dynamique est toujours (?) Va être une chaîne. Vous devez maintenant combiner ce code HTML dynamique hiérarchisé avec n’importe quel code HTML littéral, direct à afficher ... dans une structure de noeud HTML significative.

Cela oblige généralement le développeur à envelopper tout le contenu affiché directement dans une chaîne (comme le disait JD Isaak) afin qu'il puisse être correctement envoyé/inséré en conjonction avec le code HTML dynamique ... même si vous ne le faites pas vraiment. je veux qu'il soit emballé. 

Mais en utilisant les méthodes ob _ ##, vous pouvez éviter ce désordre qui enveloppe les chaînes. Le contenu littéral est plutôt envoyé dans la mémoire tampon. Ensuite, en une étape simple, tout le contenu du tampon (tout votre littéral html) est concaténé dans votre chaîne dynamique-html. 

(Mon exemple montre que du code HTML littéral est en cours de sortie dans la mémoire tampon, qui est ensuite ajoutée à une chaîne HTML. Regardez également l'exemple de JD Isaaks pour afficher 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>
7
dsdsdsdsd

Cette fonction ne concerne pas que les en-têtes. Vous pouvez faire beaucoup de choses intéressantes avec cela. 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 générée ici et l'ajouter à deux endroits totalement différents de votre mise en page.

3
jwueller

Les éléments suivants ne sont pas mentionnés dans les réponses existantes: Configuration de la taille de la mémoire tampon En-tête HTTP Et Imbrication. 

Configuration de la taille de la mémoire tampon pour ob_start:

ob_start(null, 4096); // Once the buffer size exceeds 4096 bytes, PHP automatically executes flush, ie. the buffer is emptied and sent out.

Le code ci-dessus améliore les performances du serveur car PHP enverra de plus grandes quantités de données, par exemple 4 Ko (sans appel ob_start, php enverra chaque écho au navigateur). 

Si vous démarrez la mise en mémoire tampon sans la taille du bloc (c'est-à-dire un simple ob_start ()), la page sera envoyée une fois à la fin du script.

La mise en mémoire tampon de sortie n'affecte pas les en-têtes HTTP, ils sont traités de manière différente. Cependant, en raison de la mise en mémoire tampon, vous pouvez envoyer les en-têtes même après l'envoi de la sortie, car celle-ci se trouve toujours dans la mémoire tampon.

ob_start();  // turns on output buffering
$foo->bar();  // all output goes only to buffer
ob_clean();  // delete the contents of the buffer, but remains buffering active
$foo->render(); // output goes to buffer
ob_flush(); // send buffer output
$none = ob_get_contents();  // buffer content is now an empty string
ob_end_clean();  // turn off output buffering

Bien expliqué ici: https://phpfashion.com/everything-about-outout-buffering-in-php

0
sudip

Non, vous avez tort, mais la direction est la même;)

Output-Buffering tamponne la sortie d'un script. C'est (en bref) tout après echo ou print. Le problème avec les en-têtes est qu'ils ne peuvent être envoyés que s'ils ne le sont pas déjà. Mais HTTP dit que les en-têtes sont les tous premiers de la transmission. Ainsi, si vous exportez quelque chose pour la première fois (dans une requête), les en-têtes sont envoyés et vous ne pouvez pas définir d'autres en-têtes.

0
KingCrunch