À quoi sert ob start() en php?

Est ob_start() utilisé pour output buffering , de sorte que les en-têtes sont mises en mémoire tampon et n'est pas envoyée au navigateur? Suis-je donner un sens ici? Dans la négative, pourquoi utiliser ob_start() ?

229
demandé sur jfmercer 2010-12-09 21:53:14

9 réponses

pensez à ob_start() comme disant" commencez à vous souvenir de tout ce qui serait normalement sorti, mais ne faites rien encore 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 y a deux autres fonctions que vous associez typiquement: ob_get_contents() , qui vous donne essentiellement ce qui a été "sauvé" au tampon depuis qu'il a été allumé avec ob_start() , et puis ob_end_clean() ou ob_flush() , qui soit arrête de sauver des choses et écarte ce qui a été sauvegardé, ou arrête de le sauvegarder et le sort d'un seul coup, respectivement.

364
répondu Riley Dutton 2012-09-24 11:29:29

j'utilise ceci pour pouvoir sortir de PHP avec beaucoup de HTML mais pas le rendre. Ça m'évite de le stocker comme une chaîne de caractères qui désactive le codage par couleur.

<?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>';
?>
124
répondu JD Isaacks 2010-12-09 19:03:45

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

comme indiqué ailleurs ob_start() crée une mémoire tampon à laquelle la sortie est écrite.

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

quant au pourquoi....

  1. envoyer HTML to the browser en gros morceaux offre un avantage de performance grâce à une réduction des frais généraux du réseau.

  2. transférer les données hors de PHP en gros morceaux donne un avantage de performance et de capacité en réduisant le nombre de commutateurs de contexte requis

  3. le fait de passer de plus gros blocs de données à mod_gzip/mod_deflate procure un avantage de performance en ce sens que la compression peut être plus efficace.

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

  5. explicitement rinçage la mémoire tampon après la sortie [de la tête]....[/head] peut permettre au navigateur de commencer à regrouper d'autres ressources pour la page avant que le flux HTML ne soit terminé.

  6. Capturer la sortie dans un tampon signifie qu'il peut redirigés vers d'autres fonctions telles que l'email, ou copié dans un fichier comme une représentation en cache du contenu

63
répondu symcbean 2017-08-04 19:42:37

vous l'avez à l'envers. ob_start ne cache pas les en-têtes, il protège le contenu. L'utilisation de ob_start vous permet de conserver le contenu dans un tampon côté serveur jusqu'à ce que vous soyez prêt à l'afficher.

ceci est communément utilisé pour que les pages puissent envoyer des en-têtes 'après' ils ont 'déjà envoyé' du contenu (c'est-à-dire décider de rediriger à mi-chemin en rendant une page).

28
répondu Craige 2010-12-09 18:57:43

je préfère:

ob_start();
echo("Hello there!");
$output = ob_get_clean(); //Get current buffer contents and delete current output buffer
11
répondu hawx 2015-03-13 12:02:57

ceci est pour clarifier davantage la réponse de JD Isaaks ...

le problème que vous rencontrez souvent est que vous utilisez php pour produire du html à partir de nombreuses sources php différentes, et ces sources sont souvent, pour quelque raison que ce soit, la sortie par différents moyens.

parfois, vous avez un contenu HTML littéral que vous voulez afficher directement sur le navigateur; d'autres fois, la sortie est créée dynamiquement (côté serveur).

le le contenu dynamique est toujours(?) va être une chaîne de caractères. Maintenant, vous devez combiner ce html dynamique stringifié avec n'importe quel html littéral, direct-to-display ... dans une structure de noeud html significative.

cela oblige habituellement le développeur à envelopper tout ce contenu direct-to-display dans une chaîne (comme JD Isaak en parlait) afin qu'il puisse être correctement livré/inséré en conjonction avec le html dynamique ... même si tu ne veux pas vraiment l'emballer.

Mais en utilisant les méthodes ob_## vous pouvez éviter ce désordre de string-wrapping. Le contenu littéral est, à la place, affiché dans le tampon. Puis, en une étape facile, tout le contenu du tampon (tout votre html littéral), est concaténé dans votre chaîne dynamique-html.

(mon exemple montre que le html littéral est sorti vers le tampon, qui est ensuite ajouté à une chaîne html ... regardez aussi L'exemple de JD Isaaks pour voir 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
répondu dsdsdsdsd 2013-04-09 13:06:02

cette fonction n'est pas réservée aux en-têtes. Vous pouvez faire beaucoup de choses intéressantes avec ce. 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.

3
répondu jwueller 2010-12-09 18:57:16

Non, vous avez tort, mais la direction s'adapte ;)

le tampon de sortie tamponne la sortie d'un script. C'est (en bref) tout après echo ou print . La chose avec les en-têtes est qu'ils ne peuvent être envoyés, s'ils ne sont pas déjà envoyés. Mais HTTP dit que les en-têtes sont les premiers de la transmission. Donc si vous produisez 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
répondu KingCrunch 2010-12-09 18:57:49

choses Suivantes ne sont pas mentionnés dans les réponses : Configuration de la taille du tampon L'en-Tête HTTP et de Nidification.

configuration de la taille du 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 gros morceaux de données, par exemple, 4KB (appel wihout ob_start, php enverra chaque écho au navigateur).

si vous commencez à tamponner sans la taille du morceau (c.-à-d. simple ob_start()), alors la page sera envoyé une fois à la fin du script.

Le 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 tampon, vous pouvez envoyer les en-têtes même après que la sortie a été envoyée, parce qu'elle est toujours dans le 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-output-buffering-in-php

0
répondu sudip 2018-08-23 07:33:32