Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h2>No output before sending headers!</h2> <p>Functions that send/modify HTTP headers must be invoked <strong><em>before any output is made</em></strong>. <kbd><a href="https://stackoverflow.com/a/8028979/345031"><strong>summary ⇊</strong></a></kbd> Otherwise the call fails:</p> <blockquote> <p>Warning: Cannot modify header information - headers already sent (output started at <i>script:line</i>)</p> </blockquote> <p>Some functions modifying the HTTP header are:</p> <ul> <li><a href="http://php.net/header" rel="noreferrer"><code>header</code></a> / <a href="http://php.net/header_remove" rel="noreferrer"><code>header_remove</code></a></li> <li><a href="http://php.net/session_start" rel="noreferrer"><code>session_start</code></a> / <a href="http://php.net/session_regenerate_id" rel="noreferrer"><code>session_regenerate_id</code></a></li> <li><a href="http://php.net/setcookie" rel="noreferrer"><code>setcookie</code></a> / <a href="http://php.net/setrawcookie" rel="noreferrer"><code>setrawcookie</code></a></li> </ul> <p>Output can be:</p> <ul> <li><p><em>Unintentional:</em></p> <ul> <li>Whitespace before <code>&lt;?php</code> or after <code>?&gt;</code></li> <li>The <a href="http://en.wikipedia.org/wiki/Byte_order_mark" rel="noreferrer">UTF-8 Byte Order Mark</a> specifically</li> <li>Previous error messages or notices</li> </ul></li> </ul> <ul> <li><p><em>Intentional:</em></p> <ul> <li><code>print</code>, <code>echo</code> and other functions producing output</li> <li>Raw <code>&lt;html&gt;</code> sections prior <code>&lt;?php</code> code. </li> </ul></li> </ul> <h2>Why does it happen?</h2> <p>To understand why headers must be sent before output it's necessary to look at a typical <a href="http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol" rel="noreferrer">HTTP</a> response. PHP scripts mainly generate HTML content, but also pass a set of HTTP/CGI headers to the webserver:</p> <pre><code>HTTP/1.1 200 OK Powered-By: PHP/5.3.7 Vary: Accept-Encoding Content-Type: text/html; charset=utf-8 &lt;html&gt;&lt;head&gt;&lt;title&gt;PHP page output page&lt;/title&gt;&lt;/head&gt; &lt;body&gt;&lt;h1&gt;Content&lt;/h1&gt; &lt;p&gt;Some more output follows...&lt;/p&gt; and &lt;a href="/"&gt; &lt;img src=internal-icon-delayed&gt; &lt;/a&gt; </code></pre> <p>The page/output always <em>follows</em> the headers. PHP has to pass the headers to the webserver first. It can only do that once. After the double linebreak it can nevermore amend them.</p> <p>When PHP receives the first output (<code>print</code>, <code>echo</code>, <code>&lt;html&gt;</code>) it will <em>flush</em> all collected headers. Afterwards it can send all the output it wants. But sending further HTTP headers is impossible then.</p> <h2>How can you find out where the premature output occured?</h2> <p>The <code>header()</code> warning contains all relevant information to locate the problem cause:</p> <blockquote> <p>Warning: Cannot modify header information - headers already sent by <strong><em>(output started at</em></strong> /www/usr2345/htdocs/<b>auth.php:52</b>) in /www/usr2345/htdocs/index.php on line 100</p> </blockquote> <p>Here "line 100" refers to the script where the <code>header()</code> <em>invocation</em> failed.</p> <p>The "<em>output started at</em>" note within the parenthesis is more significant. It denominates the source of previous output. In this example it's <code>auth.php</code> and <strong>line <code>52</code></strong>. That's where you had to look for premature output.</p> <p><em>Typical causes:</em></p> <ol> <li><h3>Print, echo</h3> <p>Intentional output from <code>print</code> and <code>echo</code> statements will terminate the opportunity to send HTTP headers. The application flow must be restructured to avoid that. Use <a href="http://php.net/function" rel="noreferrer">functions</a> and templating schemes. Ensure <code>header()</code> calls occur <em>before</em> messages are written out.</p> <p>Functions that produce output include</p> <ul> <li><code>print</code>, <code>echo</code>, <code>printf</code>, <code>vprintf</code></li> <li><code>trigger_error</code>, <code>ob_flush</code>, <code>ob_end_flush</code>, <code>var_dump</code>, <code>print_r</code></li> <li><code>readfile</code>, <code>passthru</code>, <code>flush</code>, <code>imagepng</code>, <code>imagejpeg</code></li> </ul> <p><br> among others and user-defined functions.</p></li> <li><h3>Raw HTML areas</h3> <p>Unparsed HTML sections in a <code>.php</code> file are direct output as well. Script conditions that will trigger a <code>header()</code> call must be noted before <em>any</em> raw <code>&lt;html&gt;</code> blocks.</p> <pre><code>&lt;!DOCTYPE html&gt; &lt;?php // Too late for headers already. </code></pre> <p>Use a templating scheme to separate processing from output logic.</p> <ul> <li>Place form processing code atop scripts.</li> <li>Use temporary string variables to defer messages.</li> <li>The actual output logic and intermixed HTML output should follow last.<br> <br></li> </ul></li> <li><h3>Whitespace before <code>&lt;?php</code> for "script.php <strong>line 1</strong>" warnings</h3> <p>If the warning refers to output in line <strong><code>1</code></strong>, then it's mostly leading <strong>whitespace</strong>, text or HTML before the opening <code>&lt;?php</code> token.</p> <pre><code> &lt;?php # There's a SINGLE space/newline before &lt;? - Which already seals it. </code></pre> <p>Similarly it can occur for appended scripts or script sections:</p> <pre><code>?&gt; &lt;?php </code></pre> <p>PHP actually eats up a <em>single</em> linebreak after close tags. But it won't compensate multiple newlines or tabs or spaces shifted into such gaps.</p></li> <li><h3>UTF-8 BOM</h3> <p>Linebreaks and spaces alone can be a problem. But there are also "invisible" character sequences which can cause this. Most famously the <a href="http://en.wikipedia.org/wiki/Byte_order_mark" rel="noreferrer"><strong>UTF-8 BOM</strong> (Byte-Order-Mark)</a> which isn't displayed by most text editors. It's the byte sequence <code>EF BB BF</code>, which is optional and redundant for UTF-8 encoded documents. PHP however has to treat it as raw output. It may show up as the characters <code></code> in the output (if the client interprets the document as Latin-1) or similar "garbage".</p> <p>In particular graphical editors and Java based IDEs are oblivious to its presence. They don't visualize it (obliged by the Unicode standard). Most programmer and console editors however do:</p> <p><img src="https://i.stack.imgur.com/aXgWY.png" width="590" height="140" alt="joes editor showing UTF-8 BOM placeholder, and MC editor a dot"></p> <p>There it's easy to recognize the problem early on. Other editors may identify its presence in a file/settings menu (Notepad++ on Windows can identify and <a href="https://stackoverflow.com/questions/3589358/fix-utf8-bom">remedy the problem</a>), Another option to inspect the BOMs presence is resorting to an <strong>hexeditor</strong>. On *nix systems <a href="http://linux.die.net/man/1/hexdump" rel="noreferrer"><code>hexdump</code></a> is usually available, if not a graphical variant which simplifies auditing these and other issues:</p> <p><img src="https://i.stack.imgur.com/QyqUr.png" width="560" height="87" alt="beav hexeditor showing utf-8 bom"></p> <p>An easy fix is to set the text editor to save files as "UTF-8 (no BOM)" or similar such nomenclature. Often newcomers otherwise resort to creating new files and just copy&amp;pasting the previous code back in.</p> <h3>Correction utilities <img src="https://i.stack.imgur.com/wnAS9.gif" width="30" height="20"></h3> <p>There are also automated tools to examine and rewrite text files (<a href="https://stackoverflow.com/questions/1068650/using-awk-to-remove-the-byte-order-mark"><code>sed</code>/<code>awk</code></a> or <code>recode</code>). For PHP specifically there's the <a href="http://freshcode.club/projects/phptags" rel="noreferrer"><code>phptags</code> tag tidier</a>. It rewrites close and open tags into long and short forms, but also easily fixes leading and trailing whitespace, Unicode and UTF-x BOM issues:</p> <pre><code>phptags --whitespace *.php </code></pre> <p>It's sane to use on a whole include or project directory.</p></li> <li><h3>Whitespace after <code>?&gt;</code></h3> <p>If the error source is mentioned as behind the <a href="https://stackoverflow.com/questions/4410704/php-closing-tag">closing <code>?&gt;</code></a> then this is where some whitespace or raw text got written out. The PHP end marker does not terminate script executation at this point. Any text/space characters after it will be written out as page content still.</p> <p>It's commonly advised, in particular to newcomers, that trailing <code>?&gt;</code> PHP close tags should be omitted. This <em>eschews</em> a small portion of these cases. (Quite commonly <code>include()d</code> scripts are the culprit.)</p></li> <li><h3>Error source mentioned as "Unknown on line 0"</h3> <p>It's typically a PHP extension or php.ini setting if no error source is concretized.</p> <ul> <li>It's occasionally the <code>gzip</code> stream encoding setting <a href="https://stackoverflow.com/questions/622192/php-warning-headers-already-sent-in-unknown">or the <code>ob_gzhandler</code></a>.</li> <li>But it could also be any doubly loaded <code>extension=</code> module generating an implicit PHP startup/warning message.<br> <br></li> </ul></li> <li><h3>Preceding error messages</h3> <p>If another PHP statement or expression causes a warning message or notice being printeded out, that also counts as premature output.</p> <p>In this case you need to eschew the error, delay the statement execution, or suppress the message with e.g. <a href="http://php.net/isset" rel="noreferrer"><code>isset()</code></a> or <a href="http://php.net/@" rel="noreferrer"><code>@()</code></a> - when either doesn't obstruct debugging later on.</p></li> </ol> <h2>No error message</h2> <p>If you have <code>error_reporting</code> or <code>display_errors</code> disabled per <code>php.ini</code>, then no warning will show up. But ignoring errors won't make the problem go away. Headers still can't be sent after premature output.</p> <p>So when <code>header("Location: ...")</code> redirects silently fail it's very advisable to probe for warnings. Reenable them with two simple commands atop the invocation script:</p> <pre><code>error_reporting(E_ALL); ini_set("display_errors", 1); </code></pre> <p>Or <code>set_error_handler("var_dump");</code> if all else fails.</p> <p>Speaking of redirect headers, you should often use an idiom like this for final code paths:</p> <pre><code>exit(header("Location: /finished.html")); </code></pre> <p>Preferrably even a utility function, which prints a user message in case of <code>header()</code> failures.</p> <h2>Output buffering as workaround</h2> <p>PHPs <a href="http://www.php.net/manual/en/intro.outcontrol.php" rel="noreferrer">output buffering</a> is a workaround to alleviate this issue. It often works reliably, but shouldn't substitute for proper application structuring and separating output from control logic. Its actual purpose is minimizing chunked transfers to the webserver.</p> <ol> <li><p>The <a href="http://php.net/manual/en/outcontrol.configuration.php" rel="noreferrer"><code>output_buffering=</code></a> setting nevertheless can help. Configure it in the <a href="http://www.php.net/manual/en/configuration.file.php" rel="noreferrer">php.ini</a> or via <a href="http://www.php.net/manual/en/configuration.changes.php" rel="noreferrer">.htaccess</a> or even <a href="http://php.net/manual/en/configuration.file.per-user.php" rel="noreferrer">.user.ini</a> on modern FPM/FastCGI setups.<br> Enabling it will allow PHP to buffer output instead of passing it to the webserver instantly. PHP thus can aggregate HTTP headers.</p></li> <li><p>It can likewise be engaged with a call to <a href="http://php.net/ob_start" rel="noreferrer"><code>ob_start();</code></a> atop the invocation script. Which however is less reliable for multiple reasons:</p> <ul> <li><p>Even if <code>&lt;?php ob_start(); ?&gt;</code> starts the first script, whitespace or a BOM might get shuffled before, <a href="https://stackoverflow.com/questions/2168956/php-header-problem-even-i-use-ob-start-and-ob-end-flush">rendering it ineffective</a>.</p></li> <li><p>It can conceal whitespace for HTML output. But as soon as the application logic attempts to send binary content (a generated image for example), the buffered extraneous output becomes a problem. (Necessitating <code>ob_clean()</code> as furher workaround.)</p></li> <li><p>The buffer is limited in size, and can easily overrun when left to defaults. And that's not a rare occurence either, <a href="https://stackoverflow.com/questions/17643837/php-headers-already-sent-error-depending-on-output-length">difficult to track down</a> when it happens.</p></li> </ul></li> </ol> <p>Both approaches therefore may become unreliable - in particular when switching between development setups and/or production servers. Which is why output buffering is widely considered just a crutch / strictly a workaround.</p> <p>See also the <a href="http://www.php.net/manual/en/outcontrol.examples.basic.php" rel="noreferrer">basic usage example</a> in the manual, and for more pros and cons:</p> <ul> <li><a href="https://stackoverflow.com/questions/2832010/what-is-output-buffering">What is output buffering?</a></li> <li><a href="https://stackoverflow.com/questions/2148114/why-use-output-buffering-in-php">Why use output buffering in PHP?</a></li> <li><a href="https://stackoverflow.com/questions/4731375/is-using-output-buffering-considered-a-bad-practice">Is using output buffering considered a bad practice?</a></li> <li><a href="https://stackoverflow.com/questions/2919569/use-case-for-output-buffering-as-the-correct-solution-to-headers-already-sent">Use case for output buffering as the correct solution to &quot;headers already sent&quot;</a></li> </ul> <h3>But it worked on the other server!?</h3> <p>If you didn't get the headers warning before, then the <a href="http://php.net/manual/en/outcontrol.configuration.php" rel="noreferrer">output buffering php.ini setting</a> has changed. It's likely unconfigured on the current/new server.</p> <h2>Checking with <code>headers_sent()</code></h2> <p>You can always use <a href="http://php.net/headers_sent" rel="noreferrer"><code>headers_sent()</code></a> to probe if it's still possible to... send headers. Which is useful to conditionally print an info or apply other fallback logic.</p> <pre><code>if (headers_sent()) { die("Redirect failed. Please click on this link: &lt;a href=...&gt;"); } else{ exit(header("Location: /user.php")); } </code></pre> <p>Useful fallback workarounds are:</p> <ul> <li><h3>HTML <code>&lt;meta&gt;</code> tag</h3> <p>If your application is structurally hard to fix, then an easy (but somewhat unprofessional) way to allow redirects is injecting a HTML <code>&lt;meta&gt;</code> tag. A redirect can be achieved with:</p> <pre><code> &lt;meta http-equiv="Location" content="http://example.com/"&gt; </code></pre> <p>Or with a short delay:</p> <pre><code> &lt;meta http-equiv="Refresh" content="2; url=../target.html"&gt; </code></pre> <p>This leads to non-valid HTML when utilized past the <code>&lt;head&gt;</code> section. Most browsers still accept it.</p></li> <li><h3>JavaScript redirect</h3> <p>As alternative a <a href="https://stackoverflow.com/questions/503093/how-can-i-make-a-redirect-page-in-jquery-javascript">JavaScript redirect</a> can be used for page redirects:</p> <pre><code> &lt;script&gt; location.replace("target.html"); &lt;/script&gt; </code></pre> <p>While this is often more HTML compliant than the <code>&lt;meta&gt;</code> workaround, it incurs a reliance on JavaScript-capable clients.</p></li> </ul> <p>Both approaches however make acceptable fallbacks when genuine HTTP header() calls fail. Ideally you'd always combine this with a user-friendly message and clickable link as last resort. (Which for instance is what the <a href="http://php.net/http_redirect" rel="noreferrer">http_redirect()</a> PECL extension does.)</p> <h2>Why <code>setcookie()</code> and <code>session_start()</code> are also affected</h2> <p>Both <code>setcookie()</code> and <code>session_start()</code> need to send a <code>Set-Cookie:</code> HTTP header. The same conditions therefore apply, and similar error messages will be generated for premature output situations.</p> <p>(Of course they're furthermore affected by disabled cookies in the browser, or even proxy issues. The session functionality obviously also depends on free disk space and other php.ini settings, etc.)</p> <h2>Further links</h2> <ul> <li>Google provides a <a href="http://www.google.com/search?q=php+headers+already+sent" rel="noreferrer">lengthy list of similar discussions</a>.</li> <li>And of course <a href="https://stackoverflow.com/search?q=[php]+headers+already+sent">many specific cases</a> have been covered on Stack Overflow as well.</li> <li>The Wordpress FAQ explains <a href="http://codex.wordpress.org/FAQ_Troubleshooting#How_do_I_solve_the_Headers_already_sent_warning_problem.3F" rel="noreferrer">How do I solve the Headers already sent warning problem?</a> in a generic manner.</li> <li>Adobe Community: <a href="http://kb2.adobe.com/community/publishing/505/cpsid_50572.html" rel="noreferrer">PHP development: why redirects don't work (headers already sent)</a></li> <li>Nucleus FAQ: <a href="http://faq.nucleuscms.org/item/79" rel="noreferrer">What does "page headers already sent" mean?</a></li> <li>One of the more thorough explanations is <a href="http://web.archive.org/web/20080430141149/http://www.expertsrt.com/tutorials/Matt/HTTP_headers.html" rel="noreferrer">HTTP Headers and the PHP header() Function - A tutorial by NicholasSolutions</a> (Internet Archive link). It covers HTTP in detail and gives a few guidelines for rewriting scripts.</li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload