15 Stimmen

Streaming der Ausgabe in eine Datei und den Browser

Ich suche also nach etwas Effizienterem als diesem:

<?php
ob_start();
include 'test.php';
$content = ob_get_contents();

file_put_contents('test.html', $content);

echo $content;
?>

Die Probleme mit den oben genannten Punkten:

  • Der Kunde erhält keine Informationen, bis die gesamte Seite gerendert ist.
  • Die Datei könnte riesig sein, daher möchte ich nicht alles im Speicher haben.

Irgendwelche Vorschläge?

0 Stimmen

Sie meinen, dass test.php (oder das Ergebnis der Auswertung) riesig sein kann?

0 Stimmen

Das Ergebnis der Evaluierung könnte enorm sein.

6voto

pix0r Punkte 30911

Interessantes Problem; ich glaube, ich habe noch nie versucht, dieses Problem zu lösen.

Ich denke, Sie brauchen eine zweite Anfrage, die von Ihrem PHP-Skript an der Vorderseite zu Ihrem Server geht. Dies könnte ein einfacher Aufruf sein an http://localhost/test.php . Wenn Sie fopen-wrappers verwenden, könnten Sie fread() verwenden, um die Ausgabe von test.php zu ziehen, während sie gerendert wird, und nach jedem empfangenen Chunk diese auf dem Bildschirm ausgeben und an Ihre Datei test.html anhängen.

So könnte das aussehen (ungetestet!):

<?php
$remote_fp = fopen("http://localhost/test.php", "r");
$local_fp = fopen("test.html", "w");
while ($buf = fread($remote_fp, 1024)) {
    echo $buf;
    fwrite($local_fp, $buf);
}
fclose($remote_fp);
fclose($local_fp);
?>

3voto

Ein besserer Weg, dies zu tun, ist die Verwendung der ersten beiden Parameter, die von ob_start : output_callback y chunk_size . Ersteres gibt einen Callback an, um die Ausgabe zu verarbeiten, während sie gepuffert wird, und letzteres gibt die Größe der zu verarbeitenden Ausgabebrocken an.

Hier ist ein Beispiel:

$output_file = fopen('test.html', 'w');
if ($output_file === false) {
    // Handle error
}

$write_ob_to_file = function($buffer) use ($output_file) {
    fwrite($output_file, $buffer);

    // Output string as-is
    return false;
};

ob_start($write_ob_to_file, 4096);
include 'test.php';
ob_end_flush();

fclose($output_file);

In diesem Beispiel wird der Ausgabepuffer alle 4096 Bytes geleert (gesendet) (und ein weiteres Mal am Ende durch die ob_end_flush Aufruf). Jedes Mal, wenn der Puffer geleert wird, wird der Callback $write_ob_to_file wird aufgerufen und der letzte Chunk übergeben. Dieser wird in test.html geschrieben. Der Callback gibt dann zurück false , d.h. "diesen Chunk so ausgeben, wie er ist". Wenn Sie die Ausgabe nur in eine Datei und nicht in den Ausgabestrom von PHP schreiben wollen, können Sie stattdessen einen leeren String zurückgeben.

0voto

Brent Punkte 22596

Die Antwort von Pix0r ist das, was Sie wollen, es sei denn, Sie brauchen es tatsächlich "eingeschlossen" und nicht nur ausgeführt. Wenn Sie zum Beispiel Anmeldeinformationen vor der test.php haben, werden diese nicht in die Datei übernommen, wenn Sie sie mit fopen aufrufen.

Wenn Sie brauchen es wirklich enthalten, dann, was Sie haben, ist die einfachste Methode, aber wenn Sie konstante Ausgabe möchten, müssen Sie tatsächlich schreiben test.php in einer Weise, die sowohl Ausgaben als auch speichert die Informationen, wie es geht. Soweit ich weiß, gibt es keine Möglichkeit, sowohl Puffer zu sammeln als auch auszugeben, während Sie gehen.

-2voto

mike Punkte 4561

Hier ist es x-send-datei Verwenden Sie mod_xsendfile, um Dateien effizient und einfach zu versenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X