Come risolvere il Warning “Cannot modify header information – headers already sent”

Come risolvere il Warning “Cannot modify header information – headers already sent”

Sin da quando ero su AlterVista, e poi sul precedente hosting (server.it), usavo uno scriptino “singolo file” per accedere ad un’area protetta personale e svolgere determinate funzioni, e questo ha sempre funzionato correttamente.

Lo script conteneva codice html e un form con php per controllare la validità della password, e quindi – se corretta – svolgere un redirect in php (header location).

Purtroppo, avendolo fatto tanto tempo fa questo script (quando ne sapevo molto meno che adesso – e adesso non è che ne sappia poi molto :lol:, lo avevo strutturato in modo errato e cioè inserendo l’header location in mezzo ad altro codice, e questo è sbagliato!

Il problema è che l’errore mi si è palesato solo adesso, sul nuovo hosting, e adesso vi spiego il perché…

Gli header: Quando noi “interroghiamo” una pagina, ci arrivano prima gli header (le intestazioni, le informazioni di base) e solo dopo il codice html.

Inserire altri header dopo aver già inviato un carattere qualunque [1],  pertanto, è sbagliato e quindi causa l’avviso “Cannot modify header information – headers already sent” ovvero: “non posso modificare le informazioni header, header già inviati”

1) con carattere qualunque si intende anche un solo spazio – e bisogna fare attenzione alla codifica che potrebbe inserire caratteri nascosti!

Esempio di codice errato:

<!DOCTYPE html>
<html lang="it-IT" dir="ltr">
  <head>
  <meta charset="utf-8">
	<title>esempio</title>
  </head>
  <body>
	<div id="page">
	<?php
	if(!isset($_POST['pass']))
	{
		echo '
		<h1>Ciao...</h1>
		<qui form che verifica la password...>';
	}
	else
	{
		header('Location: https://...');
	}
	?>
	</div>
  </body>
</html>

Error_log:

[04-May-2016 18:50:51 Europe/Rome] PHP Warning: Cannot modify header information - headers already sent by (output started at /home/***/***/folder/scriptname.php:14) in /home/***/***/folder/scriptname.php on line 29

Precedente host nessun problema, e su AV nessun problema.

Allora perché su questo host – VHosting – non funzionava?

… In ogni caso, l’errore è palese, e correggo immediatamente lo script portando prima di tutto l’header, e solo dopo l’output:

<?php

if(isset($_POST['pass']))
{
	header('Location: http://...'); // header all'inizio dello script! 
}
else
{
...

Adesso non ho più problemi, ma – da bravo curioso – voglio ancora capire “perché?”!

Faccio alcune ricerche, e scopro che potrebbe dipendere dall’output_buffering!

The Output Control functions allow you to control when output is sent from the script. This can be useful in several different situations, especially if you need to send headers to the browser after your script has begun outputting data. The Output Control functions do not affect headers sent using header() or setcookie(), only functions such as echo and data between blocks of PHP code.

In pratica, senza output buffering la pagina viene mandata come generata (header e codice – e se c’è un altro header ecco che nasce il problema)!

Con l’output buffering, invece, tutto viene precaricato in memoria, e solo dopo inviato al browser!

Quindi, grazie all’output buffering, eventuali header piazzati male verranno correttamente eseguiti senza generare alcun errore!

Così verifico su AV e su VHosting:

<?php echo ini_get('output_buffering');

Risultato:

0 (zero) qui su Vhosting, 4096 su AlterVista.

Bene, certamente dipendeva da questo!

Allora provo ad abilitarlo tramite il php.ini che vhosting – sia benedetto – mi fornisce:

Php.ini:

; output buffering output_buffering =On

E questo restituisce “1”.

Ok, allora funziona e, infatti, riprovando il mio script buggato, riesco ad eseguirlo senza più problemi 😀

In ogni caso, come su altervista, fisso il valore a 4096 (che è quello maggiormente usato e consigliato).

; output buffering output_buffering =4096

Riprovo giusto per scrupolo, e tutto rimane perfettamente funzionante!

Da adesso manterrò abilitato l’output buffering così eviterò di ritrovarmi in queste circostanze, ma sempre meglio avere lo script corretto 😉

Spero che questa esperienza possa tornarvi utile, e che se vi ritroverete questo problema, da adesso, grazie a questo articolo, saprete come risolvere.




Lascia un commento

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.