Was nützt ob_start () in PHP?


298

Wird ob_start()für verwendet, output bufferingdamit die Header gepuffert und nicht an den Browser gesendet werden? Mache ich hier Sinn? Wenn nicht, warum sollten wir dann verwenden ob_start()?

Antworten:


481

Stellen Sie sich vor ob_start(), Sie sagen: "Erinnern Sie sich an alles, was normalerweise ausgegeben wird, aber machen Sie noch nichts damit."

Zum Beispiel:

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

Es gibt zwei weitere Funktionen, mit denen Sie es normalerweise koppeln: ob_get_contents()Sie erhalten im Grunde alles, was seit dem Einschalten im Puffer "gespeichert" wurde ob_start(), und dann ob_end_clean()oder ob_flush(), das entweder das Speichern von Dingen beendet und das Gespeicherte verwirft oder das Speichern beendet und gibt alles auf einmal aus.


55
Tolle Erklärung. Ich würde noch einen Schritt weiter gehen und ersetzen ob_get_contents()mit ob_get_clean()und entfernen , ob_end_clean()da im ob_get_clean()Wesentlichen beide Funktionen ausführt. Referenz: php.net/manual/en/function.ob-get-clean.php (PHP 4> = 4.3.0, PHP 5)
Con Antonakos

Ich gehe davon aus, dass die Ausgabepufferung in der Reihenfolge der INI-Dateien aktiviert sein muss, um sie aufzurufen. ob_start();Ist dies korrekt? Was passiert, wenn es nicht aktiviert ist?
Kevin Wheeler

5
@ Riley Dutton Sie sagen nicht, warum das ob_start () verwendet wird
Vishnu R Nair

Hatte das gleiche Problem, nachdem ich meinen Code ob_end_cleandamit repariert habe , funktioniert es wie ein Zauber! Vielen Dank @ Riley Dutton
Martins

160

Ich benutze dies, damit ich mit viel HTML aus PHP ausbrechen kann, es aber nicht rendern kann. Es erspart mir das Speichern als Zeichenfolge, die die IDE-Farbcodierung deaktiviert.

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

Anstatt:

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

1
Kann dies verwendet werden, um mehrere HTML-Seiten in einem PHP zu haben und sie über GET aufzurufen?
Joshkrz

1
Ich denke schon, aber es klingt nicht nach einer guten Idee. Es wäre besser, sie aus separaten Vorlagen zu laden.
JD Isaacks

1
Beachten Sie, dass diese Technik ob_get_clean()nicht verwendet ob_end_clean()
Blazemonger

11
Ich habe nie daran gedacht, das ist eine unglaublich IDE-freundliche Art, sich zu entwickeln! Außerdem muss ich kein Javascript oder HTML mehr als Zeichenfolge in meinem PHP haben und entkomme ständig "usw.", was ärgerlich ist
J-Dizzle

1
Ihr Bild gibt ein klares Bild über die Vorteile der Verwendung von ob_start.
Klewis

86

Die hier akzeptierte Antwort beschreibt, was ob_start()funktioniert - nicht warum es verwendet wird (was die gestellte Frage war).

Wie an anderer Stelle angegeben, ob_start()wird ein Puffer erstellt, in den die Ausgabe geschrieben wird.

Aber niemand hat erwähnt, dass es möglich ist, mehrere Puffer in PHP zu stapeln. Siehe ob_get_level ().

Was das Warum betrifft ....

  1. Das Senden von HTML an den Browser in größeren Blöcken bietet einen Leistungsvorteil durch einen geringeren Netzwerk-Overhead.

  2. Das Übergeben der Daten aus PHP in größeren Blöcken bietet einen Leistungs- und Kapazitätsvorteil, indem die Anzahl der erforderlichen Kontextwechsel verringert wird

  3. Das Übergeben größerer Datenblöcke an mod_gzip / mod_deflate bietet einen Leistungsvorteil, da die Komprimierung effizienter sein kann.

  4. Durch das Puffern der Ausgabe können Sie die HTTP-Header später im Code noch bearbeiten

  5. Durch explizites Leeren des Puffers nach der Ausgabe von [head] .... [/ head] kann der Browser beginnen, andere Ressourcen für die Seite zu sammeln, bevor der HTML-Stream abgeschlossen ist.

  6. Das Erfassen der Ausgabe in einem Puffer bedeutet, dass sie zu anderen Funktionen wie E-Mail umgeleitet oder als zwischengespeicherte Darstellung des Inhalts in eine Datei kopiert werden kann


29

Du hast es rückwärts. ob_start puffert die Header nicht, sondern den Inhalt. Mit ob_startkönnen Sie den Inhalt in einem serverseitigen Puffer aufbewahren, bis Sie bereit sind, ihn anzuzeigen.

Dies wird üblicherweise verwendet, damit Seiten Header senden können, nachdem sie bereits Inhalte gesendet haben (dh sich entschieden haben, die Hälfte des Renderns einer Seite umzuleiten).


3
+1 Auch ich war verwirrt über die tatsächliche Nutzung der Funktion. Ihre Antwort bezüglich der Verwendung während der "Umleitung" erinnerte mich an alle Zeiten, in denen ich den Fehler "Header bereits gesendet" hatte. Danke
Pat

13

Ich bevorzuge:

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

8

Dies soll JD Isaaks Antwort weiter klären ...

Das Problem, auf das Sie häufig stoßen, ist, dass Sie PHP verwenden, um HTML von vielen verschiedenen PHP-Quellen auszugeben, und diese Quellen werden häufig, aus welchem ​​Grund auch immer, auf unterschiedliche Weise ausgegeben.

Manchmal haben Sie wörtlichen HTML-Inhalt, den Sie direkt an den Browser ausgeben möchten. In anderen Fällen wird die Ausgabe dynamisch erstellt (serverseitig).

Der dynamische Inhalt wird immer (?) Eine Zeichenfolge sein. Jetzt müssen Sie dieses stringifizierte dynamische HTML mit jedem wörtlichen, direkt anzuzeigenden HTML ... in einer aussagekräftigen HTML-Knotenstruktur kombinieren.

Dies zwingt den Entwickler normalerweise dazu, den gesamten direkt anzuzeigenden Inhalt in eine Zeichenfolge zu packen (wie JD Isaak besprochen hat), damit er in Verbindung mit dem dynamischen HTML-Code ordnungsgemäß bereitgestellt / eingefügt werden kann ... auch wenn Sie dies nicht wirklich tun will es verpackt.

Mit den Methoden ob _ ## können Sie jedoch das Durcheinander von Zeichenfolgen vermeiden. Der Literalinhalt wird stattdessen in den Puffer ausgegeben. Dann wird in einem einfachen Schritt der gesamte Inhalt des Puffers (Ihr gesamtes Literal-HTML) in Ihre Dynamic-HTML-Zeichenfolge verkettet.

(Mein Beispiel zeigt, wie Literal-HTML in den Puffer ausgegeben wird, der dann zu einer HTML-Zeichenfolge hinzugefügt wird. Sehen Sie sich auch das Beispiel von JD Isaaks an, um zu sehen, wie HTML-Zeichenfolgen umbrochen werden.)

<?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>

4

Diese Funktion ist nicht nur für Header. Damit kann man viele interessante Sachen machen. Beispiel: Sie können Ihre Seite in Abschnitte aufteilen und wie folgt verwenden:

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

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

Sie können die hier generierte Ausgabe erfassen und an zwei völlig unterschiedlichen Stellen in Ihrem Layout hinzufügen.


Diese Art sieht aus wie das, wonach ich suche. Ich muss Sachen in 'Abschnitte' rendern (denken Sie an JS- und CSS-Dateien), aber ich muss sie in der Vorlage aufrufen können (die später als der Header geladen wird) ... Also, wenn ich "$ this-" aufrufe. > addcss ('spezifischCSStoThisView'); " Ich möchte, dass es zwischen den <head> -Tags gerendert wird. Ich kann dies jedoch nicht googeln. Könnten Sie mich vielleicht in die richtige Richtung weisen? Danke dir!
NoobishPro

2

Folgende Dinge werden in den vorhandenen Antworten nicht erwähnt: Konfiguration der Puffergröße HTTP-Header und Verschachtelung.

Konfiguration der Puffergröße für 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.

Der obige Code verbessert die Serverleistung, da PHP größere Datenmengen sendet, z. B. 4 KB (ohne ob_start-Aufruf sendet PHP jedes Echo an den Browser).

Wenn Sie mit dem Puffern ohne die Blockgröße beginnen (dh ein einfaches ob_start ()), wird die Seite am Ende des Skripts einmal gesendet.

Die Ausgabepufferung wirkt sich nicht auf die HTTP-Header aus, sie werden auf unterschiedliche Weise verarbeitet. Aufgrund der Pufferung können Sie die Header jedoch auch nach dem Senden der Ausgabe senden, da sie sich noch im Puffer befindet.

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

Schön erklärt hier: https://phpfashion.com/everything-about-output-buffering-in-php


0

Nein, du liegst falsch, aber die Richtung passt;)

Die Ausgabepufferung puffert die Ausgabe eines Skripts. Das ist (kurz gesagt) alles nach echooder print. Die Sache mit den Headern ist, dass sie nur gesendet werden können, wenn sie nicht bereits gesendet wurden. Aber HTTP sagt, dass Header die allerersten der Übertragung sind. Wenn Sie also zum ersten Mal (in einer Anfrage) etwas ausgeben, werden die Header gesendet und Sie können keine anderen Header festlegen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.