PHP/Ausgabesteuerung

Aus Mikiwiki
< PHP
Wechseln zu: Navigation, Suche

Pufferung

Normalerweise werden von PHP mit "echo" oder "print" erzeugte Daten ebenso wie reiner HTML-Code sofort an den Webbrowser gesendet. Es kann deshalb nicht über diese Ausgaben verfügt werden. In PHP5 sind Funktionen verfügbar, mit denen der Ausgabepuffer direkt kontrolliert werden kann. Grundsätzlich kann per Funktion die Pufferung aktiviert werden, anschliessend kann der Inhalt bearbeitet werden. Dazu sind folgende Eigenschaften verwendbar:

  • Zuugriff auf den Inhalt des Puffers
  • Löschen des Puffers
  • Starten und Beenden der Pufferung

Funktionsübersicht

Die folgende Übersicht zeigt alle Pufferfunktionen; das Präfix "ob" steht für "output buffer".

Funktion Beschreibung
ob_end_clean Löscht den Puffer und beendet die Pufferung.
ob_clean Löscht den Puffer und behält den vorherigen Zustand der Pufferung bei.
ob_end_flush Beendet die Pufferung und sendet den gesamten Pufferinhalt an den Webbrowser.
flush Sendet den gesamten Pufferinhalt an den Webbrowser, beeinflusst die Pufferung jedoch nicht.
ob_get_contents Holt den Pufferinhalt und gibt ihn als Zeichenkette zurück.
ob_get_clean Holt den Pufferinhalt und gibt ihn als Zeichenkette zurück, anschliessend wird der Puffer danach gelöscht.
ob_get_level Die Pufferung arbeitet verschachtelt. Das bedeutet, dass jeder Aufruf von "ob_start" einen neuen Puffer erzeugt. Die Funktion "ob_get_level" gibt die Anzahl der verschachtelten Puffer zurück.
ob_implicit_flush Deaktiviert die Pufferung und sorgt dafür, dass Pufferinhalte nach Abschluss eines Blocks sofort gesendet werden.
ob_start Aktiviert die Pufferung und startet einen neuen Puffer. Wurde bereits ein Puffer gestartet, so wird ein neuer angelegt. Der Start eines weiteren Puffers führt zu einer Verschachtelung der Puffer, sodass sich verschiedene Programmteile den Puffer nicht teilen müssen. Die Funktion "ob_get_level" gibt die Anzahl der verschachtelten Puffer zurück.
ob_list_handlers Gibt ein Array aller Handler zurück, die der Ausgabepuffer aktuell verwendet. Handler filtern den Ausgabedatenstrom, beispielsweise zum Komprimieren.
ob_get_status Gibt ein Array mit dem Status aller Puffer zurück.
ob_get_length Gibt die Grösse des Ausgabepuffers in Byte zurück.
ob_gzhandler Eine Rückrüffunktion für "ob_start", welche die Komprimierung des Ausgabedatenstroms nach dem ZIP-Verfahren erlaubt.
ob_start("ob_gzhandler");

Anwendungsbeispiele

Das folgende Beispiel erzeugt eine HTML-Datei und schreibt sie in ein Verzeichnis, anschliessend wird sie ausgegeben. Zu beachten ist, dass das Skript mit Schreibrechten abgearbeitet werden muss. Die zu schreibende Datei (hier "sample_buffer.txt") muss vom HTTP-Server ins Verzeichnis des aufrufenden Skripts geschrieben werden können. Mit "ob_end_clean();" anstelle von "flush();" würde der Text nicht parallel zum Webbrowser geschickt.

<?php
ob_end_flush();
ob_start();
echo "Diese Datei (sample_buffer.txt) wurde dynamisch erzeugt\n";
$handleFile = fopen("sample_buffer.txt", "w");
fwrite($handleFile, ob_get_contents());
fclose($handleFile);
flush();
?>
<hr noshade size="1">
<p>Ausgabe des ursprünglichen Puffers:</p>
<p>
<?php
readfile("sample_buffer.txt");
?>

Diese Datei (sample_buffer.txt) wurde dynamisch erzeugt


Ausgabe des ursprünglichen Puffers:

Diese Datei (sample_buffer.txt) wurde dynamisch erzeugt

Das folgende Beispiel zeigt die Wirkung des Puffers, indem mehrere Ausgaben zeitlich verzögert erscheinen, was nur ohne Puffer sichtbar wird. Die "#"-zeichen werden im Abstand von etwa einer Sekunde nacheinander ausgegeben.

<?php
function delay() 
{
  $start = time();
  while ($start == time()) { }
}
ob_implicit_flush();
for ($i = 0; $i < 7; $i++, print "#", delay()) 
{
}
?>
#######

Der gepufferte Inhalt kann auch weiterverarbeitet werden. Das folgende Beispielskript gibt untereinander Pärchen von "#"-zeichen aus. Dabei wird das erste Zeichen mit "print" vom Puffer geschrieben, dann wird innerhalb der Verzögerungsfunktion der Pufferinhalt mit "echo ob_get_contents();" noch einmal ausgegeben. Anschliessend wird der Zeilenumbruch gesendet und gelöscht.

<?php
function delay() 
{
  echo ob_get_contents();
  echo "<br>";
  ob_end_flush();
  ob_start();
}
ob_start();
for ($i = 0; $i < 7; $i++, print "#", delay()) { }
?>
##
##
##
##
##
##
##

Komprimierte Datenübertragung

Bei aktivierter oder kompilierter Zlib kann PHP einzelne Datenströme im ZIP-Format packen. Die meisten Webbrowser akzeptieren dies auch. Bei der Ausgabe des Puffers kann nun festgelegt werden, dass vor der Übertragung zum Webserver und damit zum Webbrowser ein sogenannter Handler benutzt wird; eingebaut ist die Funktion "ob_gzhandler", die dies übernimmt. Sie wird allerdings nicht direkt aufgerufen, sondern als Parameter der Funktion "ob_start". Die Funktion prüft selbst, ob der Webbrowser die Kodierung akzeptiert. Das erfolgt durch Auswertung des entsprechenden Attributs im Header der Anforderung.

ob_start("ob_gzhandler");

Um die Fähigkeiten des Webbrowsers selbst festzustellen, genügt folgende Zeile.

<?php
echo $_SERVER['HTTP_ACCEPT_ENCODING'];
?>
gzip,deflate