Community Pick: Many members of our community have endorsed this article.

Warning: Cannot modify header information - headers already sent...

Published:
Updated:
Introduction
This warning has to be one of the most commonly issued warnings in the history of PHP.  The article explains why this warning arises and what to do to mitigate the problem.

How this Happens
HTTP headers include many different kinds of information that can be exchanged between the browser and the server.  But as the name "header" implies, they must come only at the beginning of the server's response to the client request.  It is a law of the HTTP protocol that all headers must come first, have been sent, and completed before any browser output can be sent.  In PHP, the "Cannot Modify Header Information" always means that some browser output was sent, and then a PHP header() function was called.  To quote the PHP web site, "Remember that header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP.  It is a very common error to read code with include(), or require(), functions, or another file access function, and have spaces or empty lines that are output before header() is called.  The same problem exists when using a single PHP/HTML file."

All by itself, "whitespace" can cause this error.  Consider this code snippet.  The middle line apparently contains "nothing" but it actually contains a newline character and that single (invisible) character is sufficient to cause the warning.  
 
<?php // whitespace_header_error.php
                      error_reporting(E_ALL);
                      // DROP OUT OF PHP INTO HTML
                      ?>
                      
                      <?php
                      // RESUME PHP PROCESSING AND TRY TO REDIRECT TO THE HOME PAGE
                      header('Location: /');
                      exit();

Open in new window

In the case of code with include(), a common error would look something like this.  Nothing is apparently wrong with this script.  But inside the "thing.php" script you might find something like the next snippet.  There is an invisible trailing blank after the end-of-php signal ?>
 
<?php // whitespace_header_error.php
                      error_reporting(E_ALL);
                      include_once('thing.php');
                      header('Location: /');
                      exit();

Open in new window


<?php // thing.php
                      /* LOTS OF CODE HERE */
                      ?>
                       

Open in new window

There is no need to close any PHP script with ?> unless it is followed by HTML.  Modern coding standards recommend against using the end-of-php tag unless it is absolutely necessary.  Because the thing.php script closed out PHP, it dropped into HTML and the server sent an end-of-line character to the browser output stream.  That is enough to signal the permanent end of headers.  

What about Cookies?
Another common error is the use of setcookie() after browser output.  Cookies are headers, too!  You must follow the same guidance for setcookie() as you follow for header().

What about the PHP Session?
The PHP session uses HTTP cookies.  It follows that you want to use session_start() at the logical beginning of your script.

Solve the Problem with Program Logic
Solve this problem by looking carefully at your code to be sure you are only starting the session, setting cookies, or sending headers at the logical beginning of a script.  

Solve the Problem with Output Buffering
If your program logic is such that you start to create a web page, but then need to redirect (if for example the client is not logged in), you can use output buffering to capture the browser output.  PHP has the ob_start() function to help with this.  Call it once at the top of your script and nothing will be sent to the browser until your script ends.  So if we look at our whitespace_header_error script, this one line change (line 3) will be sufficient:
 
<?php // whitespace_header_success.php
                      error_reporting(E_ALL);
                      ob_start();
                      ?>
                      ANYTHING YOU WANT HERE!
                      <?php
                      header('Location: /');
                      exit();

Open in new window

You can start output buffering in your PHP code, or you can add a configuration option to your PHP installation.  Output buffering is off by default, but is settable via php.ini.  Either way, you will pick up performance benefits when you use output buffering because the server will not have to repeatedly connect and disconnect to send each little piece of HTML output -- it can all be sent at once.

Summary
We have learned why  our scripts may generate this warning, and how to remediate our program logic to avoid the problem. We have also learned about PHP output buffering, a feature that can solve the warning and simultaneously improve the performance of our PHP scripts.

Useful links for further reading:
http://php.net/manual/en/function.header.php
http://php.net/manual/en/function.headers-sent.php
http://php.net/manual/en/function.setcookie.php
http://php.net/manual/en/function.session-start.php
http://php.net/manual/en/function.ob-start.php
http://www.ietf.org/rfc/rfc2616.txt
http://www.ietf.org/rfc/rfc2109.txt
http://wikipedia.org/wiki/List_of_HTTP_header_fields
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
https://addons.mozilla.org/en-us/firefox/addon/live-http-headers/

Please give us your feedback!
If you found this article helpful, please click the "thumb's up" button below. Doing so lets the E-E community know what is valuable for E-E members and helps provide direction for future articles.  If you have questions or comments, please add them.  Thanks!
 
5
6,021 Views

Comments (0)

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.