However, if you get an error "Headers already sent" as the first error and it tells you the error is near the end of a file (check which file "output started at" points to), that probably means that there are extra spaces or lines after a closing ?> php tag.
This error message gets triggered when anything is sent before you send HTTP headers (with setcookie or header ).
The first thing you need to do when you run into the “Cannot modify header information – headers already sent by” error is to open the file that's causing the problem. Then, locate the line the message indicates. In this scenario, you can reach the source of the problem using the WordPress theme editor.
Yup, you can use the headers_sent function. Checks if or where headers have been sent. You can't add any more header lines using the header() function once the header block has already been sent. Using this function you can at least prevent getting HTTP header related error messages.
Functions that send/modify HTTP headers must be invoked before any output is made. summary ⇊ Otherwise the call fails:
Warning: Cannot modify header information - headers already sent (output started at script:line)
Some functions modifying the HTTP header are:
header
/ header_remove
session_start
/ session_regenerate_id
setcookie
/ setrawcookie
Output can be:
Unintentional:
<?php
or after ?>
Intentional:
print
, echo
and other functions producing output<html>
sections prior <?php
code.To understand why headers must be sent before output it's necessary to look at a typical HTTP response. 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=internal-icon-delayed> </a>
The page/output always follows 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.
When PHP receives the first output (print
, echo
, <html>
) it will
flush all collected headers. Afterward it can send all the output
it wants. But sending further HTTP headers is impossible then.
The header()
warning contains all relevant information to
locate the problem cause:
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 "output started at" note within the parenthesis is more significant.
It denominates the source of previous output. In this example, it's auth.php
and line 52
. That's where you had to look for premature output.
Typical causes:
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 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 and user-defined functions.
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.
Use a templating scheme to separate processing from output logic.
<?php
for "script.php line 1" warningsIf the warning refers to output inline 1
, then it's mostly
leading whitespace, text or HTML before the opening <?php
token.
<?php
# There's a SINGLE space/newline before <? - Which already seals it.
Similarly it can 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.
Linebreaks and spaces alone can be a problem. But there are also "invisible"
character sequences that can cause this. Most famously the
UTF-8 BOM (Byte-Order-Mark)
which isn't displayed by most text editors. It's the byte sequence EF BB BF
, 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 
in the output (if the client interprets the document as Latin-1) or similar "garbage".
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:
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
remedy the problem),
Another option to inspect the BOMs presence is resorting to an hexeditor.
On *nix systems hexdump
is usually available,
if not a graphical variant which simplifies auditing these and other issues:
An easy fix is to set the text editor to save files as "UTF-8 (no BOM)" or similar to such nomenclature. Often newcomers otherwise resort to creating new files and just copy&pasting the previous code back in.
There are also automated tools to examine and rewrite text files
(sed
/awk
or recode
).
For PHP specifically there's the phptags
tag tidier.
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:
phptags --whitespace *.php
It's safe to use on a whole include or project directory.
?>
If the error source is mentioned as behind the
closing ?>
then this is where some whitespace or the raw text got written out.
The PHP end marker does not terminate script execution at this point. Any text/space characters after it will be written out as page content
still.
It's commonly advised, in particular to newcomers, that trailing ?>
PHP
close tags should be omitted. This eschews a small portion of these cases.
(Quite commonly include()d
scripts are the culprit.)
It's typically a PHP extension or php.ini setting if no error source is concretized.
gzip
stream encoding setting
or the ob_gzhandler
.extension=
module
generating an implicit PHP startup/warning message.If another PHP statement or expression causes a warning message or notice being printed out, that also counts as premature output.
In this case you need to eschew the error,
delay the statement execution, or suppress the message with e.g.
isset()
or @()
-
when either doesn't obstruct debugging later on.
If you have error_reporting
or display_errors
disabled per php.ini
,
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.
So when header("Location: ...")
redirects silently fail it's very
advisable to probe for warnings. Reenable them with two simple commands
atop the invocation script:
error_reporting(E_ALL);
ini_set("display_errors", 1);
Or set_error_handler("var_dump");
if all else fails.
Speaking of redirect headers, you should often use an idiom like this for final code paths:
exit(header("Location: /finished.html"));
Preferably even a utility function, which prints a user message
in case of header()
failures.
PHPs output buffering 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.
The output_buffering=
setting nevertheless can help.
Configure it in the php.ini
or via .htaccess
or even .user.ini on
modern FPM/FastCGI setups.
Enabling it will allow PHP to buffer output instead of passing it to the webserver instantly. PHP thus can aggregate HTTP headers.
It can likewise be engaged with a call to ob_start();
atop the invocation script. Which however is less reliable for multiple reasons:
Even if <?php ob_start(); ?>
starts the first script, whitespace or a
BOM might get shuffled before, rendering it ineffective.
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 ob_clean()
as a further workaround.)
The buffer is limited in size, and can easily overrun when left to defaults. And that's not a rare occurrence either, difficult to track down when it happens.
Both approaches therefore may become unreliable - in particular when switching between development setups and/or production servers. This is why output buffering is widely considered just a crutch / strictly a workaround.
See also the basic usage example in the manual, and for more pros and cons:
If you didn't get the headers warning before, then the output buffering php.ini setting has changed. It's likely unconfigured on the current/new server.
headers_sent()
You can always use headers_sent()
to probe if
it's still possible to... send headers. Which is useful to conditionally print
info or apply other fallback logic.
if (headers_sent()) {
die("Redirect failed. Please click on this link: <a href=...>");
}
else{
exit(header("Location: /user.php"));
}
Useful fallback workarounds are:
<meta>
tagIf your application is structurally hard to fix, then an easy (but
somewhat unprofessional) way to allow redirects is injecting a HTML
<meta>
tag. A redirect can be achieved with:
<meta http-equiv="Location" content="http://example.com/">
Or with a short delay:
<meta http-equiv="Refresh" content="2; url=../target.html">
This leads to non-valid HTML when utilized past the <head>
section.
Most browsers still accept it.
As alternative a JavaScript redirect can be used for page redirects:
<script> location.replace("target.html"); </script>
While this is often more HTML compliant than the <meta>
workaround,
it incurs a reliance on JavaScript-capable clients.
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 http_redirect() PECL extension does.)
setcookie()
and session_start()
are also affectedBoth setcookie()
and session_start()
need to send a Set-Cookie:
HTTP header.
The same conditions therefore apply, and similar error messages will be generated
for premature output situations.
(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.)
This error message gets triggered when anything is sent before you send HTTP headers (with setcookie
or header
). Common reasons for outputting something before the HTTP headers are:
Accidental whitespace, often at the beginning or end of files, like this:
<?php
// Note the space before "<?php"
?>
To avoid this, simply leave out the closing ?>
- it's not required anyways.
3F 3C
. You can safely remove the BOM EF BB BF
from the start of files.echo
, printf
, readfile
, passthru
, code before <?
etc.display_errors
php.ini property is set. Instead of crashing on a programmer mistake, php silently fixes the error and emits a warning. While you can modify the display_errors
or error_reporting configurations, you should rather fix the problem.$_POST['input']
without using empty
or isset
to test whether the input is set), or using an undefined constant instead of a string literal (as in $_POST[input]
, note the missing quotes).Turning on output buffering should make the problem go away; all output after the call to ob_start
is buffered in memory until you release the buffer, e.g. with ob_end_flush
.
However, while output buffering avoids the issues, you should really determine why your application outputs an HTTP body before the HTTP header. That'd be like taking a phone call and discussing your day and the weather before telling the caller that he's got the wrong number.
I got this error many times before, and I am certain all PHP programmer got this error at least once before.
Possible Solution 1
This error may have been caused by the blank spaces before the start of the file or after the end of the file.These blank spaces should not be here.
ex) THERE SHOULD BE NO BLANK SPACES HERE
echo "your code here";
?>
THERE SHOULD BE NO BLANK SPACES HERE
Check all files associated with file that causes this error.
Note: Sometimes EDITOR(IDE) like gedit (a default linux editor) add one blank line on save file. This should not happen. If you are using Linux. you can use VI editor to remove space/lines after ?> at the end of the page.
Possible Solution 2: If this is not your case, then use ob_start to output buffering:
<?php
ob_start();
// code
ob_end_flush();
?>
This will turn output buffering on and your headers will be created after the page is buffered.
Instead of the below line
//header("Location:".ADMIN_URL."/index.php");
write
echo("<script>location.href = '".ADMIN_URL."/index.php?msg=$msg';</script>");
or
?><script><?php echo("location.href = '".ADMIN_URL."/index.php?msg=$msg';");?></script><?php
It'll definitely solve your problem. I faced the same problem but I solved through writing header location in the above way.
You do
printf ("Hi %s,</br />", $name);
before setting the cookies, which isn't allowed. You can't send any output before the headers, not even a blank line.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With