Recent Posts

Showing posts with label headers already sent. Show all posts
Showing posts with label headers already sent. Show all posts

How to fix "Headers already sent" in PHP

No output before sending headers!

Functions that send/modify HTTP headers must be invoked before any output is made. Otherwise the call fails:

Warning: Cannot modify header information - headers already sent (output started at file:line)

Some functions modifying the HTTP header are:

  • header / header_remove
  • session_start / session_regenerate_id
  • setcookie / setrawcookie
Output can be:

Unintentional


Intentional

  • printecho and other functions producing output (like var_dump)
  • Raw <html> areas before <?php code.

Why does it happen?

To understand why headers must be sent before output it's necessary to look at a typical HTTPresponse. PHP scripts mainly generate HTML content, but also pass a set of HTTP/CGI headers to the webserver:

HTTP/1.1 200 OK
 Powered-By: PHP/5.3.7
 Vary: Accept-Encoding
 Content-Type: text/html; charset=utf-8

 <html><head><title>PHP page output page</title></head>
 <body><h1>Content</h1> <p>Some more output follows...</p>
 and <a href="/"> <img src=about:note> ...

The page/output always follows the headers. PHP is required to pass the headers to the webserver first. It can only do that once. And after the double linebreak it can't ever append to them again.
When PHP receives the first output (print,echo,`) it will "flush" the collected headers. Afterwards it can send all the output bits it wants. But sending further headers is impossible from then.

How can you find out where the premature output occured?

The header() warning contains all relevant information to locate the problem source:
Warning: Cannot modify header information - headers already sent by (output started at/www/usr2345/htdocs/auth.php:52) in /www/usr2345/htdocs/index.php on line 100
Here "line 100" refers to the script where the header() invocation failed.
The message in the inner parenthesis is more crucial. It mentions auth.php and line 52 as the source of premature output. One of the typical problem causes will be there:

Print, echo

Intentional output from print and echo statements will terminate the opportunity to send HTTP headers. The application flow must be restructured to avoid that. Use functions and templating schemes. Ensure header() calls occur before messages are written out.
Functions that can write output include printechoprintftrigger_errorvprintfob_flushvar_dumpreadfilepassthru among others and user-defined functions.

Raw HTML areas

Unparsed HTML sections in a .php file are direct output as well. Script conditions that will trigger a header() call must be noted before any raw <html> blocks.
<!DOCTYPE html>
<?php
    // Too late for headers already.

Whitespace before <?php when "somefile.php line 1" mentioned

If the message says the error is in line 1, then it is typically leading whitespace, text or HTML before the opening <?php marker.
 <?php
# There's a SINGLE! space/newline before <? - Which already seals it.
It can likewise occur for appended scripts or script sections:
?>

<?php
PHP actually eats up a single linebreak after close tags. But it won't compensate multiple newlines or tabs or spaces shifted into such gaps.