Warning: Cannot modify header information. Chiariamo una volta per tutte

Dimmi la verità: almeno una volta hai fatto a pugni con questo errore, vero?
In questa pillola metteremo in chiaro, una volta per tutte, come si verifica questo errore, come evitarlo e, se non è possibile evitarlo, come eventualmente aggirarlo.

Quando viene sollevato questo errore?

Alcune funzioni di PHP aggiungono delle informazioni agli headers che il web server invia al browser quando richiede una pagina. Le principali funzioni di questo tipo sono:

  • header()
  • setcookie()
  • session_start()

Non appena in un documento abbiamo un output (qualsiasi output), il web server inizia ad inviare gli headers al client. Questo ad esempio è l’header che mi invia Your Inspiration Web

Date: Mon, 01 Nov 2010 13:55:15 GMT
Server: Apache/2.2.15 (Unix) mod_ssl/2.2.15 OpenSSL/0.9.8e-fips-rhel5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635
X-Powered-By: PHP/5.2.13
Vary: Cookie
Expires: Wed, 11 Jan 1984 05:00:00 GMT
X-Pingback: https://www.yourinspirationweb.com/xmlrpc.php
Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache
WP-Super-Cache: Served legacy cache file
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

200 OK

Se settassi un cookie verrebbe aggiunta una riga come questa
Set-Cookie: nome=valore; expires=timestamp della scadenza del cookie

Ora, se scriviamo

echo “Ciao”;
 

il web server rilascerà gli headers non appena incontra questa istruzione.
A questo punto i buoi sono fuori dalla stalla, quindi se volessi ad esempio impostare un cookie, non potrei più farlo. Infatti i dati del cookie sono inviati nell’header della richiesta, ma l’header è già partito e quindi verrà sollevato il celebre errore.

Ripeto: qualsiasi output

Anche questo script solleverà il famigerato errore


<?php // nota che c’è un “a capo” prima dell’apertura del tag php
session_start();
 //....
 

Infatti prima dell’apertura del tag PHP siamo in modalità HTML, ed in questa modalità un “a capo” è, che lo si voglia o no, un output.
Per inciso molto spesso l’errore è proprio questo (e magari è un errore contenuto in qualche file incluso e la cosa ci fa perdere molto tempo)!

Soluzioni

La soluzione è ovviamente portare le funzioni che modificano l’header all’inizio dello script o comunque prima di qualsiasi output. Questo lo si può fare nel 99,5% dei casi, anche quando sembra che non sia possibile, ed è la soluzione migliore.
Tuttavia, in rare circostanze, potrebbe non essere possibile questa procedura.
In questo caso potremo utilizzare la funzione ob_start() (da invocare all’inizio dello script). Questa funzione trattiene gli output nel buffer fino al termine dell’esecuzione dello script.
Quindi questo script non solleverà errori:

<?php ob_start(); ?>
<h1>Ciao</h1>
<?php session_start(); ?>

Questa soluzione è da usare con parsimonia in quanto lo stoccaggio degli output sul server va a pesare sulle prestazioni. Possiamo parzialmente ovviare a questo problema liberando il buffer non appena non vi è più necessità di trattenerlo tramite la funzione ob_end_flush().

<?php ob_start(); ?>
<h1>Ciao</h1>
<?php
session_start();
ob_end_flush();
//altro codice e altro contenuto ....
?>

Conclusione

In questa pillola abbiamo visto che quello che è un grattacapo per molti, in realtà è una questione semplicissima che si risolve con un minimo sforzo.
E tu? Ti sei mai trovato a litigare con questo errore?

Tag: ,

L'autore

Maurizio è sposato con la triade PHP - MySql - Apache e, non pago, ha un'amante chiamata jQuery. Ha un blog dove cerca di descrivere nei minimi particolari sia la moglie che l'amante. La sua vera specialità è la realizzazione di gestionali complessi anche se non rifiuta mai un sito web. +

Sito web dell'autore | Altri articoli scritti da

Articoli correlati

Potresti essere interessato anche ai seguenti articoli:

12 commenti

Trackback e pingback

  1. Tweets that mention [PILLOLE PHP] Warning: Cannot modify header information. Chiariamo una volta per tutte | Your Inspiration Web -- Topsy.com
    [...] This post was mentioned on Twitter by PHP Italia and mtx_maurizio, Simone D'Amico. Simone D'Amico said: [PILLOLE PHP] Warning:…