PHP/Ausgabesteuerung
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.
|
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 |