How to fix "Headers already sent" error in PHP -
when running script, getting several errors this:
warning: cannot modify header information - headers sent (output started @ /some/file.php:12) in /some/file.php on line 23
the lines mentioned in error messages contain header()
, setcookie()
calls.
what reason this? , how fix it?
no output before sending headers!
functions send/modify http headers must invoked before output made. summary ⇊ otherwise call fails:
warning: cannot modify header information - headers sent (output started @ script:line)
some functions modifying http header are:
output can be:
unintentional:
- whitespace before
<?php
or after?>
- the utf-8 byte order mark specifically
- previous error messages or notices
- whitespace before
intentional:
print
,echo
, other functions producing output- raw
<html>
sections prior<?php
code.
why happen?
to understand why headers must sent before output it's necessary @ typical http response. php scripts generate html content, pass set of http/cgi headers 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> , <a href="/"> <img src=internal-icon-delayed> </a>
the page/output follows headers. php has pass headers webserver first. can once. after double linebreak can nevermore amend them.
when php receives first output (print
, echo
, <html>
) flush collected headers. afterwards can send output wants. sending further http headers impossible then.
how can find out premature output occured?
the header()
warning contains relevant information locate problem cause:
warning: cannot modify header information - headers sent (output started at /www/usr2345/htdocs/auth.php:52) in /www/usr2345/htdocs/index.php on line 100
here "line 100" refers script header()
invocation failed.
the "output started at" note within parenthesis more significant. denominates source of previous output. in example it's auth.php
, line 52
. that's had premature output.
typical causes:
print, echo
intentional output
print
,echo
statements terminate opportunity send http headers. application flow must restructured avoid that. use functions , templating schemes. ensureheader()
calls occur before messages written out.functions produce output include
print
,echo
,printf
,vprintf
trigger_error
,ob_flush
,ob_end_flush
,var_dump
,print_r
readfile
,passthru
,flush
,imagepng
,imagejpeg
among others , user-defined functions.raw html areas
unparsed html sections in
.php
file direct output well. script conditions triggerheader()
call must noted before any raw<html>
blocks.<!doctype html> <?php // late headers already.
use templating scheme separate processing output logic.
- place form processing code atop scripts.
- use temporary string variables defer messages.
- the actual output logic , intermixed html output should follow last.
whitespace before
<?php
"script.php line 1" warningsif warning refers output in line
1
, it's leading whitespace, text or html before opening<?php
token.<?php # there's single space/newline before <? - seals it.
similarly can occur appended scripts or script sections:
?> <?php
php eats single linebreak after close tags. won't compensate multiple newlines or tabs or spaces shifted such gaps.
utf-8 bom
linebreaks , spaces alone can problem. there "invisible" character sequences can cause this. famously utf-8 bom (byte-order-mark) isn't displayed text editors. it's byte sequence
ef bb bf
, optional , redundant utf-8 encoded documents. php has treat raw output. may show characters
in output (if client interprets document latin-1) or similar "garbage".in particular graphical editors , java based ides oblivious presence. don't visualize (obliged unicode standard). programmer , console editors do:
there it's easy recognize problem on. other editors may identify presence in file/settings menu (notepad++ on windows can identify , remedy problem), option inspect boms presence resorting hexeditor. on *nix systems
hexdump
available, if not graphical variant simplifies auditing these , other issues:an easy fix set text editor save files "utf-8 (no bom)" or similar such nomenclature. newcomers otherwise resort creating new files , copy&pasting previous code in.
correction utilities
there automated tools examine , rewrite text files (
sed
/awk
orrecode
). php there'sphptags
tag tidier. rewrites close , open tags long , short forms, fixes leading , trailing whitespace, unicode , utf-x bom issues:phptags --whitespace *.php
it's sane use on whole include or project directory.
whitespace after
?>
if error source mentioned behind closing
?>
whitespace or raw text got written out. php end marker not terminate script executation @ point. text/space characters after written out page content still.it's commonly advised, in particular newcomers, trailing
?>
php close tags should omitted. eschews small portion of these cases. (quite commonlyinclude()d
scripts culprit.)error source mentioned "unknown on line 0"
it's typically php extension or php.ini setting if no error source concretized.
- it's
gzip
stream encoding setting orob_gzhandler
. - but doubly loaded
extension=
module generating implicit php startup/warning message.
- it's
preceding error messages
if php statement or expression causes warning message or notice being printeded out, counts premature output.
in case need eschew error, delay statement execution, or suppress message e.g.
isset()
or@()
- when either doesn't obstruct debugging later on.
no error message
if have error_reporting
or display_errors
disabled per php.ini
, no warning show up. ignoring errors won't make problem go away. headers still can't sent after premature output.
so when header("location: ...")
redirects silently fail it's advisable probe warnings. reenable them 2 simple commands atop invocation script:
error_reporting(e_all); ini_set("display_errors", 1);
or set_error_handler("var_dump");
if else fails.
speaking of redirect headers, should use idiom final code paths:
exit(header("location: /finished.html"));
preferrably utility function, prints user message in case of header()
failures.
output buffering workaround
phps output buffering workaround alleviate issue. works reliably, shouldn't substitute proper application structuring , separating output control logic. actual purpose minimizing chunked transfers webserver.
the
output_buffering=
setting nevertheless can help. configure in php.ini or via .htaccess or .user.ini on modern fpm/fastcgi setups.
enabling allow php buffer output instead of passing webserver instantly. php can aggregate http headers.it can likewise engaged call
ob_start();
atop invocation script. less reliable multiple reasons:even if
<?php ob_start(); ?>
starts first script, whitespace or bom might shuffled before, rendering ineffective.it can conceal whitespace html output. application logic attempts send binary content (a generated image example), buffered extraneous output becomes problem. (necessitating
ob_clean()
furher workaround.)the buffer limited in size, , can overrun when left defaults. , that's not rare occurence either, difficult track down when happens.
both approaches therefore may become unreliable - in particular when switching between development setups and/or production servers. why output buffering considered crutch / strictly workaround.
see basic usage example in manual, , more pros , cons:
- what output buffering?
- why use output buffering in php?
- is using output buffering considered bad practice?
- use case output buffering correct solution "headers sent"
but worked on other server!?
if didn't headers warning before, output buffering php.ini setting has changed. it's unconfigured on current/new server.
checking headers_sent()
you can use headers_sent()
probe if it's still possible to... send headers. useful conditionally print info or apply other fallback logic.
if (headers_sent()) { die("redirect failed. please click on link: <a href=...>"); } else{ exit(header("location: /user.php")); }
useful fallback workarounds are:
html
<meta>
tagif application structurally hard fix, easy (but unprofessional) way allow redirects injecting html
<meta>
tag. redirect can achieved with:<meta http-equiv="location" content="http://example.com/">
or short delay:
<meta http-equiv="refresh" content="2; url=../target.html">
this leads non-valid html when utilized past
<head>
section. browsers still accept it.javascript redirect
as alternative javascript redirect can used page redirects:
<script> location.replace("target.html"); </script>
while more html compliant
<meta>
workaround, incurs reliance on javascript-capable clients.
both approaches make acceptable fallbacks when genuine http header() calls fail. ideally you'd combine user-friendly message , clickable link last resort. (which instance http_redirect() pecl extension does.)
why setcookie()
, session_start()
affected
both setcookie()
, session_start()
need send set-cookie:
http header. same conditions therefore apply, , similar error messages generated premature output situations.
(of course they're furthermore affected disabled cookies in browser, or proxy issues. session functionality depends on free disk space , other php.ini settings, etc.)
further links
- google provides lengthy list of similar discussions.
- and of course many specific cases have been covered on stack overflow well.
- the wordpress faq explains how solve headers sent warning problem? in generic manner.
- adobe community: php development: why redirects don't work (headers sent)
- nucleus faq: what "page headers sent" mean?
- one of more thorough explanations http headers , php header() function - tutorial nicholassolutions (internet archive link). covers http in detail , gives few guidelines rewriting scripts.
Comments
Post a Comment