2009-03-06 11 views
10

Quindi, sto cercando qualcosa di più efficiente di questo:Streaming output in un file e il browser

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

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

echo $content; 
?> 

I problemi di cui sopra:

  • client non riceve nulla fino a quando l'intera pagina è reso
  • File potrebbe essere enorme, quindi preferisco non avere il tutto in memoria

Qualche suggerimento?

+0

vuoi dire test.php (o il risultato di una valutazione della stessa) può essere enorme? –

+0

Il risultato della valutazione potrebbe essere enorme. –

risposta

6

Interessante problema; non pensare di aver provato a risolverlo prima.

Sto pensando che sarà necessario avere una seconda richiesta che va dallo script PHP frontale al server. Questa potrebbe essere una semplice chiamata a http://localhost/test.php. Se usi fopen-wrappers, puoi usare fread() per estrarre l'output di test.php mentre viene renderizzato, e dopo che ogni chunk è stato ricevuto, stampalo sullo schermo e aggiungilo al tuo file test.html.

Ecco come che potrebbe apparire (non testata!): Risposta

<?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); 
?> 
+0

Interessante. Aggiungendo questo al mio cinturone. –

0

di Pix0r è ciò che si vuole a meno che effettivamente bisogno "incluso" piuttosto che solo eseguito. Ad esempio, se si dispone di informazioni di accesso prima del test.php, non verrà passato nel file se lo si chiama con fopen.

Se ne hai veramente bisogno, allora quello che hai è il metodo più semplice, ma se vuoi un output costante, devi scrivere in realtà test.php in un modo che produca e memorizzi le informazioni così come va. Per quanto ne so, non c'è modo di raccogliere il buffer e inviarlo come si va.

-1

Qui vai x-send-file, usa mod_xsendfile per inviare file in modo efficiente, davvero facile.

+1

Lo esaminerò, ma non risolve esattamente il mio problema. Voglio generare e trasmettere file di grandi dimensioni da PHP senza dover prima generare il file statico. Mi piacerebbe farli in parallelo. –

2

Un modo migliore per fare ciò è utilizzare i primi due parametri accettati da ob_start: output_callback e chunk_size. Il primo specifica un callback per gestire l'output in quanto è bufferizzato e quest'ultimo specifica la dimensione dei blocchi di output da gestire.

Ecco un esempio:

$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 questo esempio, il buffer di uscita viene lavata (inviato) per ogni 4096 byte di uscita (e ancora una volta alla fine dalla chiamata ob_end_flush). Ogni volta che il buffer viene svuotato, verrà richiamata la callback e verrà passato l'ultimo blocco. Questo viene scritto in test.html. Il callback restituisce quindi false, che significa "stampa questo blocco come è". Se si desidera scrivere solo l'output in un file e non nel flusso di output di PHP, è possibile restituire una stringa vuota.

Problemi correlati