HTTP (Hypertext Transfer Protocol) è la tecnologia alla base del World Wide Web ed (in parole povere) definisce la comunicazione client-server.
Quando un browser richiede una pagina Web, riceve una serie di intestazioni HTTP in cambio. Questo accade dietro le quinte, ovviamente, la maggior parte degli utenti non sono consapevoli di tutto questo.
La funzione PHP header()
può essere utilizzata per trarre vantaggio da questo protocollo.
L’esempio più comune è quello di reindirizzare il browser Web dalla pagina corrente ad un’altra.
Una cosa assolutamente necessaria da ricordare a proposito la funzione header()
è che deve essere chiamata prima che qualsiasi altra cosa sia inviata al browser.
Questo include HTML o addirittura spazi bianchi. Se il codice ha qualche istruzione echo()
o print()
, ha righe vuote al di fuori dei tags PHP, oppure include files che fanno una qualsiasi di queste cose prima di una chiamata ad header()
, verrà visualizzato un messaggio di errore.
I cookies e le sessioni permettono di superare il limite di HTTP che è un protocollo senza stato (stateless), cioè ogni pagina è un’entità a se stante.
I cookies memorizzano i dati nel browser dell’utente. Le sessioni memorizzano i dati sul server stesso.
Le sessioni sono generalmente più sicure che i cookies ed in grado di memorizzare molte più informazioni.
La cosa più importante da capire è che con PHP anche i cookies e le sessioni devono essere inviati dal server al client prima di ogni altra informazione proprio come gli headers.
Questo comportamento a volte può essere un limite per lo sviluppatore, soprattutto più che l’applicazione diventa complessa. Vediamo come possiamo baypassarlo…
Output Buffering
Per impostazione predefinita, tutto ciò che uno script PHP stampa o qualsiasi HTML al di fuori dei tags PHP (anche nei files inclusi), viene immediatamente inviato al browser.
L’output buffering ( o output control, come viene chiamato dal manuale PHP) è una funzione PHP che esegue l’override di questo comportamento. Invece di inviare subito l’HTML al browser Web, l’output verrà inserito in un buffer di memoria temporanea.
In seguito, il buffer viene svuotato, è inviato al browser (se lo desideriamo).
Ci può anche essere un miglioramento delle prestazioni con il buffering dell’output, ma il vantaggio principale è che si elimina virtualmente i fastidiosi errori sulle intestazioni (headers already sent).
Come detto in precedenza alcune funzioni, header()
, setcookie()
, e session_start()
, possono essere chiamate solo se nulla è stato inviato al browser.
Con l’ output buffering, nulla sarà inviato al browser Web fino alla fine della pagina (o comunque fino a quando non lo vogliano noi), così si è liberi di chiamare queste funzioni in qualsiasi punto dello script.
Per iniziare il buffering dell’output, usare la funzione ob_start()
. Una volta chiamata, ogni echo()
, print()
, o funzione analoga invierà i dati a un buffer di memoria piuttosto che al Web browser.
Al contrario, le chiamate HTTP (come header()
e setcookie()
) non saranno “buffered” e opereranno come di consueto.
A conclusione dello script, chiamare al ob_end_flush()
per inviare il buffer accumulato al browser. In alternativa, utilizzare la funzione ob_end_clean()
per cancellare i dati nel buffer senza inviarlo. Entrambe le funzioni hanno l’effetto secondario di disattivare il buffering dell’output.
Tips
Nelle versioni più recenti di PHP, il buffering dell’output è abilitato di default. La dimensione del buffer, il numero massimo di byte memorizzati nella memoria è pari a 4.096 (output_buffering = 4096
), ma questo può essere cambiato nel file di configurazione di PHP.
La funzione ob_get_contents()
restituirà il buffer corrente in modo che possa essere assegnato ad una variabile, in caso di necessità.
La funzione ob_flush()
invierà il contenuto corrente del buffer al browser Web per poi disfarsene, consentendo ad un nuovo buffer di partire.
Questa funzione permette di mantenere nei vostri script le dimensioni del buffer più moderate. Al contrario la, ob_end_flush()
disattiva l’output buffering dopo l’invio del buffer al browser Web.
La funzione ob_clean()
cancella il contenuto corrente del buffer senza fermare il processo di buffer.
PHP esegue automaticamente la ob_end_flush()
al termine di uno script, se non viene fatto niente di diverso.
4 risposte su “PHP – Output Buffering”
dopo 10 anni di web design mi sono messo a studiare php, e questo è il miglior articolo che ho trovato online dopo essermi scontrato con l’errore (credo classico per i principianti) “headers already sent”! anche meglio del manuale di php… grazie!
E’ un piacere dare una mano. 😉
Ti chiedo scusa se mi collego ad un tuo post vecchiotto ma mi chiedevo se potevi aiutarmi a modificare questo codice http://pastebin.com/Qv0mbM8W per sovrascrivere l’output ogni volta, invece che stampare tutto il contenuto, sommandolo ad ogni ciclo.
Si è vero che ti risolve il problema dei vari errori sui “headers already sent“, ma ti crea anche delle latenze se usi l’ xdebug sugli ide (netbeans, eclipse, etc.), rendendoti la vita un pelo fastidiosa durante il debugging.
L’ideale, sarebbe risolvere il problema degli header, ed identificare perchè accade, in modo che il tutto possa funzionare con o senza output_buffering.