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
  • 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:

  1. print, echo

    intentional output print , echo statements terminate opportunity send http headers. application flow must restructured avoid that. use functions , templating schemes. ensure header() 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.

  2. raw html areas

    unparsed html sections in .php file direct output well. script conditions trigger header() 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.

  3. whitespace before <?php "script.php line 1" warnings

    if 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.

  4. 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:

    joes editor showing utf-8 bom placeholder, , mc editor dot

    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:

    beav hexeditor showing utf-8 bom

    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 or recode). php there's phptags 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.

  5. 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 commonly include()d scripts culprit.)

  6. 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 or ob_gzhandler.
    • but doubly loaded extension= module generating implicit php startup/warning message.

  7. 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.

  1. 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.

  2. 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:

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> tag

    if 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


Comments

Popular posts from this blog

java - nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet Hibernate+SpringMVC -

sql - Postgresql tables exists, but getting "relation does not exist" when querying -

asp.net mvc - breakpoint on javascript in CSHTML? -