Rectangle 27 2

That's the HTTP refresh header which is better known as the meta refresh tag. The one in your question is the HTTP response header equivalent of the following line in HTML <head>:

<meta http-equiv="refresh" content="300" />

It will reload the current request after the given amount of seconds, as if you're pressing F5. It was an old Netscape invention and supported by most if not all browsers, but this "meta" header is not taken into the RFC 2616 - HTTP header field definitions standard. The W3C also discourages the use of this header.

This isn't the same thing as a meta tag. This is merely a "Refresh" header.

@Will: I didn't mean to say that they're the same, more that the purpose is better known to be achieved by the HTML meta tag. You can represent all HTTP response headers by HTML meta http-equiv tags. Only when an equivalent is already present in the HTTP response header, then the meta tag is ignored. However, the meta tag is always been used when the HTML resource is been opened from for example the local disk file system instead of by a HTTP request (e.g. after you save the page to disk).

java - What is the meaning of response.setHeader("Refresh", "300")? - ...

java servlets
Rectangle 27 157

As vartec says above, the HTTP spec does not define a limit, however many servers do by default. This means, practically speaking, the lower limit is 8K. For most servers, this limit applies to the sum of the request line and ALL header fields (so keep your cookies short).

It's worth noting that nginx uses the system page size by default, which is 4K on most systems. You can check with this tiny program:

#include <unistd.h>
#include <stdio.h>

int main() {
    int pageSize = getpagesize();
    printf("Page size on your system = %i bytes\n", pageSize);
    return 0;
}

Compile with gcc -o pagesize pagesize.c then run ./pagesize. My ubuntu server from Linode dutifully informs me the answer is 4k.

For apache2, URL length is controlled by LimitRequestLine and LimitRequestFieldSize applies to each HTTP header line indivually... not the "sum of..."

No need to write code to get the page size. From a terminal : getconf PAGESIZE

This has probably changed since this answer was written, but the linked nginx page doesn't match the answer. The nginx page indicates that the default buffer size is 8k, and that the request can use 4 buffers by default (the buffer size itself limits the size of the request line and each individual header). So this suggests that nginx allows for somewhere between 16-32k (I'm assuming one line can't be split across two buffers, so the buffers may not be filled all the way up).

Maximum on http header values? - Stack Overflow

http http-headers
Rectangle 27 162

As vartec says above, the HTTP spec does not define a limit, however many servers do by default. This means, practically speaking, the lower limit is 8K. For most servers, this limit applies to the sum of the request line and ALL header fields (so keep your cookies short).

It's worth noting that nginx uses the system page size by default, which is 4K on most systems. You can check with this tiny program:

#include <unistd.h>
#include <stdio.h>

int main() {
    int pageSize = getpagesize();
    printf("Page size on your system = %i bytes\n", pageSize);
    return 0;
}

Compile with gcc -o pagesize pagesize.c then run ./pagesize. My ubuntu server from Linode dutifully informs me the answer is 4k.

For apache2, URL length is controlled by LimitRequestLine and LimitRequestFieldSize applies to each HTTP header line indivually... not the "sum of..."

No need to write code to get the page size. From a terminal : getconf PAGESIZE

This has probably changed since this answer was written, but the linked nginx page doesn't match the answer. The nginx page indicates that the default buffer size is 8k, and that the request can use 4 buffers by default (the buffer size itself limits the size of the request line and each individual header). So this suggests that nginx allows for somewhere between 16-32k (I'm assuming one line can't be split across two buffers, so the buffers may not be filled all the way up).

Maximum on http header values? - Stack Overflow

http http-headers
Rectangle 27 80

There is discussion of this, including links to browser testing and backwards compatibility, in the proposed RFC 5987, "Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters."

RFC 2183 indicates that such headers should be encoded according to RFC 2184, which was obsoleted by RFC 2231, covered by the draft RFC above.

Also note that the internet draft (not "draft RFC") has been finished, and the final document is RFC 5987 (greenbytes.de/tech/webdav/rfc5987.html)

Related to this, I discovered that Firefox (versions 4-9 inclusive) break if there is a comma (,) in the filename, e.g. Content-Disposition: filename="foo, bar.pdf". The result is that firefox downloads the file correctly but keeps the .part extension (e.g foo,bar.pdf-1.part). Then, of course the file won't open correctly because the application is not associated with .part. Other ASCII chars seem to work OK.

@catchdave: You forgot the "attachment;" part.

browser - How to encode the filename parameter of Content-Disposition ...

browser http-headers specifications
Rectangle 27 79

There is discussion of this, including links to browser testing and backwards compatibility, in the proposed RFC 5987, "Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters."

RFC 2183 indicates that such headers should be encoded according to RFC 2184, which was obsoleted by RFC 2231, covered by the draft RFC above.

Also note that the internet draft (not "draft RFC") has been finished, and the final document is RFC 5987 (greenbytes.de/tech/webdav/rfc5987.html)

Related to this, I discovered that Firefox (versions 4-9 inclusive) break if there is a comma (,) in the filename, e.g. Content-Disposition: filename="foo, bar.pdf". The result is that firefox downloads the file correctly but keeps the .part extension (e.g foo,bar.pdf-1.part). Then, of course the file won't open correctly because the application is not associated with .part. Other ASCII chars seem to work OK.

@catchdave: You forgot the "attachment;" part.

browser - How to encode the filename parameter of Content-Disposition ...

browser http-headers specifications
Rectangle 27 79

There is discussion of this, including links to browser testing and backwards compatibility, in the proposed RFC 5987, "Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters."

RFC 2183 indicates that such headers should be encoded according to RFC 2184, which was obsoleted by RFC 2231, covered by the draft RFC above.

Also note that the internet draft (not "draft RFC") has been finished, and the final document is RFC 5987 (greenbytes.de/tech/webdav/rfc5987.html)

Related to this, I discovered that Firefox (versions 4-9 inclusive) break if there is a comma (,) in the filename, e.g. Content-Disposition: filename="foo, bar.pdf". The result is that firefox downloads the file correctly but keeps the .part extension (e.g foo,bar.pdf-1.part). Then, of course the file won't open correctly because the application is not associated with .part. Other ASCII chars seem to work OK.

@catchdave: You forgot the "attachment;" part.

browser - How to encode the filename parameter of Content-Disposition ...

browser http-headers specifications
Rectangle 27 78

There is discussion of this, including links to browser testing and backwards compatibility, in the proposed RFC 5987, "Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters."

RFC 2183 indicates that such headers should be encoded according to RFC 2184, which was obsoleted by RFC 2231, covered by the draft RFC above.

Also note that the internet draft (not "draft RFC") has been finished, and the final document is RFC 5987 (greenbytes.de/tech/webdav/rfc5987.html)

Related to this, I discovered that Firefox (versions 4-9 inclusive) break if there is a comma (,) in the filename, e.g. Content-Disposition: filename="foo, bar.pdf". The result is that firefox downloads the file correctly but keeps the .part extension (e.g foo,bar.pdf-1.part). Then, of course the file won't open correctly because the application is not associated with .part. Other ASCII chars seem to work OK.

@catchdave: You forgot the "attachment;" part.

browser - How to encode the filename parameter of Content-Disposition ...

browser http-headers specifications
Rectangle 27 241

Getting header values from the Initial Page Request:

Unfortunately, there isn't an API to give you the HTTP response headers for your initial page request. That was the original question posted here. It has been repeatedly asked, too, because some people would like to get the actual response headers of the original page request without issuing another one.

If an HTTP request is made over AJAX, it is possible to get the response headers with the getAllResponseHeaders() method. It's part of the XMLHttpRequest API. To see how this can be applied, check out the fetchSimilarHeaders() function below. Note that this is a work-around to the problem that won't be reliable for some applications.

myXMLHttpRequest.getAllResponseHeaders();

This will not give you information about the original page request's HTTP response headers, but it could be used to make educated guesses about what those headers were. More on that is described next.

This question was first asked several years ago, asking specifically about how to get at the original HTTP response headers for the current page (i.e. the same page inside of which the javascript was running). This is quite a different question than simply getting the response headers for any HTTP request. For the initial page request, the headers aren't readily available to javascript. Whether the header values you need will be reliably and sufficiently consistent if you request the same page again via AJAX will depend on your particular application.

The following are a few suggestions for getting around that problem.

If the response is largely static and the headers are not expected to change much between requests, you could make an AJAX request for the same page you're currently on and assume that they're they are the same values which were part of the page's HTTP response. This could allow you to access the headers you need using the nice XMLHttpRequest API described above.

function fetchSimilarHeaders (callback) {
    var request = new XMLHttpRequest();
    request.onreadystatechange = function () {
        if (request.readyState === 4) {
            //
            // The following headers may often be similar
            // to those of the original page request...
            //
            if (callback && typeof callback === 'function') {
                callback(request.getAllResponseHeaders());
            }
        }
    };

    //
    // Re-request the same page (document.location)
    // We hope to get the same or similar response headers to those which 
    // came with the current page, but we have no guarantee.
    // Since we are only after the headers, a HEAD request may be sufficient.
    //
    request.open('HEAD', document.location, true);
    request.send(null);
}

This approach will be problematic if you truly have to rely on the values being consistent between requests, since you can't fully guarantee that they are the same. It's going to depend on your specific application and whether you know that the value you need is something that won't be changing from one request to the next.

There are some BOM properties (Browser Object Model) which the browser determines by looking at the headers. Some of these properties reflect HTTP headers directly (e.g. navigator.userAgent is set to the value of the HTTP User-Agent header field). By sniffing around the available properties you might be able to find what you need, or some clues to indicate what the HTTP response contained.

If you control the server side, you can access any header you like as you construct the full response. Values could be passed to the client with the page, stashed in some markup or perhaps in an inlined JSON structure. If you wanted to have every HTTP request header available to your javascript, you could iterate through them on the server and send them back as hidden values in the markup. It's probably not ideal to send header values this way, but you could certainly do it for the specific value you need. This solution is arguably inefficient, too, but it would do the job if you needed it.

RE update: ajax requests were a standard part of web development way back in 2008 as well -_-

3) you could stash them in the http cookie header, too. Then you wouldn't need to change the document markup.

There is a simple way to access the response header elements such as the link element: use document example here: gist.github.com/FunThomas424242/

Accessing the web page's HTTP Headers in JavaScript - Stack Overflow

javascript http http-headers
Rectangle 27 241

Getting header values from the Initial Page Request:

Unfortunately, there isn't an API to give you the HTTP response headers for your initial page request. That was the original question posted here. It has been repeatedly asked, too, because some people would like to get the actual response headers of the original page request without issuing another one.

If an HTTP request is made over AJAX, it is possible to get the response headers with the getAllResponseHeaders() method. It's part of the XMLHttpRequest API. To see how this can be applied, check out the fetchSimilarHeaders() function below. Note that this is a work-around to the problem that won't be reliable for some applications.

myXMLHttpRequest.getAllResponseHeaders();

This will not give you information about the original page request's HTTP response headers, but it could be used to make educated guesses about what those headers were. More on that is described next.

This question was first asked several years ago, asking specifically about how to get at the original HTTP response headers for the current page (i.e. the same page inside of which the javascript was running). This is quite a different question than simply getting the response headers for any HTTP request. For the initial page request, the headers aren't readily available to javascript. Whether the header values you need will be reliably and sufficiently consistent if you request the same page again via AJAX will depend on your particular application.

The following are a few suggestions for getting around that problem.

If the response is largely static and the headers are not expected to change much between requests, you could make an AJAX request for the same page you're currently on and assume that they're they are the same values which were part of the page's HTTP response. This could allow you to access the headers you need using the nice XMLHttpRequest API described above.

function fetchSimilarHeaders (callback) {
    var request = new XMLHttpRequest();
    request.onreadystatechange = function () {
        if (request.readyState === 4) {
            //
            // The following headers may often be similar
            // to those of the original page request...
            //
            if (callback && typeof callback === 'function') {
                callback(request.getAllResponseHeaders());
            }
        }
    };

    //
    // Re-request the same page (document.location)
    // We hope to get the same or similar response headers to those which 
    // came with the current page, but we have no guarantee.
    // Since we are only after the headers, a HEAD request may be sufficient.
    //
    request.open('HEAD', document.location, true);
    request.send(null);
}

This approach will be problematic if you truly have to rely on the values being consistent between requests, since you can't fully guarantee that they are the same. It's going to depend on your specific application and whether you know that the value you need is something that won't be changing from one request to the next.

There are some BOM properties (Browser Object Model) which the browser determines by looking at the headers. Some of these properties reflect HTTP headers directly (e.g. navigator.userAgent is set to the value of the HTTP User-Agent header field). By sniffing around the available properties you might be able to find what you need, or some clues to indicate what the HTTP response contained.

If you control the server side, you can access any header you like as you construct the full response. Values could be passed to the client with the page, stashed in some markup or perhaps in an inlined JSON structure. If you wanted to have every HTTP request header available to your javascript, you could iterate through them on the server and send them back as hidden values in the markup. It's probably not ideal to send header values this way, but you could certainly do it for the specific value you need. This solution is arguably inefficient, too, but it would do the job if you needed it.

RE update: ajax requests were a standard part of web development way back in 2008 as well -_-

3) you could stash them in the http cookie header, too. Then you wouldn't need to change the document markup.

There is a simple way to access the response header elements such as the link element: use document example here: gist.github.com/FunThomas424242/

Accessing the web page's HTTP Headers in JavaScript - Stack Overflow

javascript http http-headers
Rectangle 27 2489

How can you find out where the premature output occured?

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

Some functions modifying the HTTP header are:

header
header_remove
session_start
session_regenerate_id
setcookie
setrawcookie
  • Whitespace before <?php or after ?>
<html>
<?php

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

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.

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.

print
echo
printf
vprintf
trigger_error
ob_flush
ob_end_flush
var_dump
print_r
readfile
passthru
flush
imagepng
imagejpeg

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.

  • The actual output logic and intermixed HTML output should follow last.

If the warning refers to output in line 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 which 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 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 sane 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 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.

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.

  • It's occasionally the gzip stream encoding setting or the ob_gzhandler.
extension=

If another PHP statement or expression causes a warning message or notice being printeded 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);
set_error_handler("var_dump");

Speaking of redirect headers, you should often use an idiom like this for final code paths:

exit(header("Location: /finished.html"));

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

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.

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.

You can always use headers_sent() to probe if it's still possible to... send headers. Which is useful to conditionally print an 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"));
}

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

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

  • And of course many specific cases have been covered on Stack Overflow as well.
  • One of the more thorough explanations is HTTP Headers and the PHP header() Function - A tutorial by NicholasSolutions (Internet Archive link). It covers HTTP in detail and gives a few guidelines for rewriting scripts.

Also regular notepad.exe is tricky. I use NetBeans normally that doesn't add BOM, even if file is encoded so. Editing a file later in notepad messes things up, especially towards IIS as webserver. It seems as apache discards the (unitentionally added) BOM.

Removing the closing ?> from the end of a php files is usually a good practice which helps minimizing these errors as well. Unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.

Strange thing, I moved my file from cPanel Linux Hosting to VPS. Before it was working properly but here it showed this error.(I had some html code before header). Why?

But it worked on the other server!?

How to fix "Headers already sent" error in PHP - Stack Overflow

php header
Rectangle 27 2489

How can you find out where the premature output occured?

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

Some functions modifying the HTTP header are:

header
header_remove
session_start
session_regenerate_id
setcookie
setrawcookie
  • Whitespace before <?php or after ?>
<html>
<?php

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

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.

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.

print
echo
printf
vprintf
trigger_error
ob_flush
ob_end_flush
var_dump
print_r
readfile
passthru
flush
imagepng
imagejpeg

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.

  • The actual output logic and intermixed HTML output should follow last.

If the warning refers to output in line 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 which 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 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 sane 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 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.

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.

  • It's occasionally the gzip stream encoding setting or the ob_gzhandler.
extension=

If another PHP statement or expression causes a warning message or notice being printeded 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);
set_error_handler("var_dump");

Speaking of redirect headers, you should often use an idiom like this for final code paths:

exit(header("Location: /finished.html"));

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

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.

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.

You can always use headers_sent() to probe if it's still possible to... send headers. Which is useful to conditionally print an 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"));
}

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

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

  • And of course many specific cases have been covered on Stack Overflow as well.
  • One of the more thorough explanations is HTTP Headers and the PHP header() Function - A tutorial by NicholasSolutions (Internet Archive link). It covers HTTP in detail and gives a few guidelines for rewriting scripts.

Also regular notepad.exe is tricky. I use NetBeans normally that doesn't add BOM, even if file is encoded so. Editing a file later in notepad messes things up, especially towards IIS as webserver. It seems as apache discards the (unitentionally added) BOM.

Removing the closing ?> from the end of a php files is usually a good practice which helps minimizing these errors as well. Unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.

Strange thing, I moved my file from cPanel Linux Hosting to VPS. Before it was working properly but here it showed this error.(I had some html code before header). Why?

But it worked on the other server!?

How to fix "Headers already sent" error in PHP - Stack Overflow

php header
Rectangle 27 2489

How can you find out where the premature output occured?

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

Some functions modifying the HTTP header are:

header
header_remove
session_start
session_regenerate_id
setcookie
setrawcookie
  • Whitespace before <?php or after ?>
<html>
<?php

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

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.

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.

print
echo
printf
vprintf
trigger_error
ob_flush
ob_end_flush
var_dump
print_r
readfile
passthru
flush
imagepng
imagejpeg

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.

  • The actual output logic and intermixed HTML output should follow last.

If the warning refers to output in line 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 which 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 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 sane 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 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.

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.

  • It's occasionally the gzip stream encoding setting or the ob_gzhandler.
extension=

If another PHP statement or expression causes a warning message or notice being printeded 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);
set_error_handler("var_dump");

Speaking of redirect headers, you should often use an idiom like this for final code paths:

exit(header("Location: /finished.html"));

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

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.

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.

You can always use headers_sent() to probe if it's still possible to... send headers. Which is useful to conditionally print an 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"));
}

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

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

  • And of course many specific cases have been covered on Stack Overflow as well.
  • One of the more thorough explanations is HTTP Headers and the PHP header() Function - A tutorial by NicholasSolutions (Internet Archive link). It covers HTTP in detail and gives a few guidelines for rewriting scripts.

Also regular notepad.exe is tricky. I use NetBeans normally that doesn't add BOM, even if file is encoded so. Editing a file later in notepad messes things up, especially towards IIS as webserver. It seems as apache discards the (unitentionally added) BOM.

Removing the closing ?> from the end of a php files is usually a good practice which helps minimizing these errors as well. Unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.

Strange thing, I moved my file from cPanel Linux Hosting to VPS. Before it was working properly but here it showed this error.(I had some html code before header). Why?

But it worked on the other server!?

How to fix "Headers already sent" error in PHP - Stack Overflow

php header
Rectangle 27 2489

How can you find out where the premature output occured?

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

Some functions modifying the HTTP header are:

header
header_remove
session_start
session_regenerate_id
setcookie
setrawcookie
  • Whitespace before <?php or after ?>
<html>
<?php

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

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.

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.

print
echo
printf
vprintf
trigger_error
ob_flush
ob_end_flush
var_dump
print_r
readfile
passthru
flush
imagepng
imagejpeg

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.

  • The actual output logic and intermixed HTML output should follow last.

If the warning refers to output in line 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 which 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 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 sane 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 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.

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.

  • It's occasionally the gzip stream encoding setting or the ob_gzhandler.
extension=

If another PHP statement or expression causes a warning message or notice being printeded 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);
set_error_handler("var_dump");

Speaking of redirect headers, you should often use an idiom like this for final code paths:

exit(header("Location: /finished.html"));

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

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.

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.

You can always use headers_sent() to probe if it's still possible to... send headers. Which is useful to conditionally print an 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"));
}

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

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

  • And of course many specific cases have been covered on Stack Overflow as well.
  • One of the more thorough explanations is HTTP Headers and the PHP header() Function - A tutorial by NicholasSolutions (Internet Archive link). It covers HTTP in detail and gives a few guidelines for rewriting scripts.

Also regular notepad.exe is tricky. I use NetBeans normally that doesn't add BOM, even if file is encoded so. Editing a file later in notepad messes things up, especially towards IIS as webserver. It seems as apache discards the (unitentionally added) BOM.

Removing the closing ?> from the end of a php files is usually a good practice which helps minimizing these errors as well. Unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.

Strange thing, I moved my file from cPanel Linux Hosting to VPS. Before it was working properly but here it showed this error.(I had some html code before header). Why?

But it worked on the other server!?

How to fix "Headers already sent" error in PHP - Stack Overflow

php header
Rectangle 27 2489

How can you find out where the premature output occured?

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

Some functions modifying the HTTP header are:

header
header_remove
session_start
session_regenerate_id
setcookie
setrawcookie
  • Whitespace before <?php or after ?>
<html>
<?php

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

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.

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.

print
echo
printf
vprintf
trigger_error
ob_flush
ob_end_flush
var_dump
print_r
readfile
passthru
flush
imagepng
imagejpeg

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.

  • The actual output logic and intermixed HTML output should follow last.

If the warning refers to output in line 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 which 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 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 sane 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 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.

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.

  • It's occasionally the gzip stream encoding setting or the ob_gzhandler.
extension=

If another PHP statement or expression causes a warning message or notice being printeded 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);
set_error_handler("var_dump");

Speaking of redirect headers, you should often use an idiom like this for final code paths:

exit(header("Location: /finished.html"));

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

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.

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.

You can always use headers_sent() to probe if it's still possible to... send headers. Which is useful to conditionally print an 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"));
}

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

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

  • And of course many specific cases have been covered on Stack Overflow as well.
  • One of the more thorough explanations is HTTP Headers and the PHP header() Function - A tutorial by NicholasSolutions (Internet Archive link). It covers HTTP in detail and gives a few guidelines for rewriting scripts.

Also regular notepad.exe is tricky. I use NetBeans normally that doesn't add BOM, even if file is encoded so. Editing a file later in notepad messes things up, especially towards IIS as webserver. It seems as apache discards the (unitentionally added) BOM.

Removing the closing ?> from the end of a php files is usually a good practice which helps minimizing these errors as well. Unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.

Strange thing, I moved my file from cPanel Linux Hosting to VPS. Before it was working properly but here it showed this error.(I had some html code before header). Why?

But it worked on the other server!?

How to fix "Headers already sent" error in PHP - Stack Overflow

php header
Rectangle 27 2488

How can you find out where the premature output occured?

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

Some functions modifying the HTTP header are:

header
header_remove
session_start
session_regenerate_id
setcookie
setrawcookie
  • Whitespace before <?php or after ?>
<html>
<?php

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

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.

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.

print
echo
printf
vprintf
trigger_error
ob_flush
ob_end_flush
var_dump
print_r
readfile
passthru
flush
imagepng
imagejpeg

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.

  • The actual output logic and intermixed HTML output should follow last.

If the warning refers to output in line 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 which 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 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 sane 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 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.

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.

  • It's occasionally the gzip stream encoding setting or the ob_gzhandler.
extension=

If another PHP statement or expression causes a warning message or notice being printeded 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);
set_error_handler("var_dump");

Speaking of redirect headers, you should often use an idiom like this for final code paths:

exit(header("Location: /finished.html"));

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

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.

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.

You can always use headers_sent() to probe if it's still possible to... send headers. Which is useful to conditionally print an 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"));
}

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

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

  • And of course many specific cases have been covered on Stack Overflow as well.
  • One of the more thorough explanations is HTTP Headers and the PHP header() Function - A tutorial by NicholasSolutions (Internet Archive link). It covers HTTP in detail and gives a few guidelines for rewriting scripts.

Also regular notepad.exe is tricky. I use NetBeans normally that doesn't add BOM, even if file is encoded so. Editing a file later in notepad messes things up, especially towards IIS as webserver. It seems as apache discards the (unitentionally added) BOM.

Removing the closing ?> from the end of a php files is usually a good practice which helps minimizing these errors as well. Unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.

Strange thing, I moved my file from cPanel Linux Hosting to VPS. Before it was working properly but here it showed this error.(I had some html code before header). Why?

But it worked on the other server!?

How to fix "Headers already sent" error in PHP - Stack Overflow

php header
Rectangle 27 2470

How can you find out where the premature output occured?

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

Some functions modifying the HTTP header are:

header
header_remove
session_start
session_regenerate_id
setcookie
setrawcookie
  • Whitespace before <?php or after ?>
<html>
<?php

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

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.

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.

print
echo
printf
vprintf
trigger_error
ob_flush
ob_end_flush
var_dump
print_r
readfile
passthru
flush
imagepng
imagejpeg

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.

  • The actual output logic and intermixed HTML output should follow last.

If the warning refers to output in line 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 which 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 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 sane 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 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.

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.

  • It's occasionally the gzip stream encoding setting or the ob_gzhandler.
extension=

If another PHP statement or expression causes a warning message or notice being printeded 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);
set_error_handler("var_dump");

Speaking of redirect headers, you should often use an idiom like this for final code paths:

exit(header("Location: /finished.html"));

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

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.

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.

You can always use headers_sent() to probe if it's still possible to... send headers. Which is useful to conditionally print an 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"));
}

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

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

  • And of course many specific cases have been covered on Stack Overflow as well.
  • One of the more thorough explanations is HTTP Headers and the PHP header() Function - A tutorial by NicholasSolutions (Internet Archive link). It covers HTTP in detail and gives a few guidelines for rewriting scripts.

Also regular notepad.exe is tricky. I use NetBeans normally that doesn't add BOM, even if file is encoded so. Editing a file later in notepad messes things up, especially towards IIS as webserver. It seems as apache discards the (unitentionally added) BOM.

Removing the closing ?> from the end of a php files is usually a good practice which helps minimizing these errors as well. Unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.

Strange thing, I moved my file from cPanel Linux Hosting to VPS. Before it was working properly but here it showed this error.(I had some html code before header). Why?

But it worked on the other server!?

How to fix "Headers already sent" error in PHP - Stack Overflow

php header
Rectangle 27 2501

How can you find out where the premature output occured?

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

Some functions modifying the HTTP header are:

header
header_remove
session_start
session_regenerate_id
setcookie
setrawcookie
  • Whitespace before <?php or after ?>
<html>
<?php

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

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.

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.

print
echo
printf
vprintf
trigger_error
ob_flush
ob_end_flush
var_dump
print_r
readfile
passthru
flush
imagepng
imagejpeg

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.

  • The actual output logic and intermixed HTML output should follow last.

If the warning refers to output in line 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 which 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 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 sane 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 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.

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.

  • It's occasionally the gzip stream encoding setting or the ob_gzhandler.
extension=

If another PHP statement or expression causes a warning message or notice being printeded 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);
set_error_handler("var_dump");

Speaking of redirect headers, you should often use an idiom like this for final code paths:

exit(header("Location: /finished.html"));

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

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.

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.

You can always use headers_sent() to probe if it's still possible to... send headers. Which is useful to conditionally print an 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"));
}

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

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

  • And of course many specific cases have been covered on Stack Overflow as well.
  • One of the more thorough explanations is HTTP Headers and the PHP header() Function - A tutorial by NicholasSolutions (Internet Archive link). It covers HTTP in detail and gives a few guidelines for rewriting scripts.

Also regular notepad.exe is tricky. I use NetBeans normally that doesn't add BOM, even if file is encoded so. Editing a file later in notepad messes things up, especially towards IIS as webserver. It seems as apache discards the (unitentionally added) BOM.

Removing the closing ?> from the end of a php files is usually a good practice which helps minimizing these errors as well. Unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.

Strange thing, I moved my file from cPanel Linux Hosting to VPS. Before it was working properly but here it showed this error.(I had some html code before header). Why?

But it worked on the other server!?

How to fix "Headers already sent" error in PHP - Stack Overflow

php header
Rectangle 27 2501

How can you find out where the premature output occured?

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

Some functions modifying the HTTP header are:

header
header_remove
session_start
session_regenerate_id
setcookie
setrawcookie
  • Whitespace before <?php or after ?>
<html>
<?php

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

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.

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.

print
echo
printf
vprintf
trigger_error
ob_flush
ob_end_flush
var_dump
print_r
readfile
passthru
flush
imagepng
imagejpeg

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.

  • The actual output logic and intermixed HTML output should follow last.

If the warning refers to output in line 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 which 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 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 sane 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 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.

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.

  • It's occasionally the gzip stream encoding setting or the ob_gzhandler.
extension=

If another PHP statement or expression causes a warning message or notice being printeded 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);
set_error_handler("var_dump");

Speaking of redirect headers, you should often use an idiom like this for final code paths:

exit(header("Location: /finished.html"));

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

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.

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.

You can always use headers_sent() to probe if it's still possible to... send headers. Which is useful to conditionally print an 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"));
}

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

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

  • And of course many specific cases have been covered on Stack Overflow as well.
  • One of the more thorough explanations is HTTP Headers and the PHP header() Function - A tutorial by NicholasSolutions (Internet Archive link). It covers HTTP in detail and gives a few guidelines for rewriting scripts.

Also regular notepad.exe is tricky. I use NetBeans normally that doesn't add BOM, even if file is encoded so. Editing a file later in notepad messes things up, especially towards IIS as webserver. It seems as apache discards the (unitentionally added) BOM.

Removing the closing ?> from the end of a php files is usually a good practice which helps minimizing these errors as well. Unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.

Strange thing, I moved my file from cPanel Linux Hosting to VPS. Before it was working properly but here it showed this error.(I had some html code before header). Why?

But it worked on the other server!?

How to fix "Headers already sent" error in PHP - Stack Overflow

php header
Rectangle 27 2501

How can you find out where the premature output occured?

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

Some functions modifying the HTTP header are:

header
header_remove
session_start
session_regenerate_id
setcookie
setrawcookie
  • Whitespace before <?php or after ?>
<html>
<?php

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

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.

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.

print
echo
printf
vprintf
trigger_error
ob_flush
ob_end_flush
var_dump
print_r
readfile
passthru
flush
imagepng
imagejpeg

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.

  • The actual output logic and intermixed HTML output should follow last.

If the warning refers to output in line 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 which 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 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 sane 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 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.

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.

  • It's occasionally the gzip stream encoding setting or the ob_gzhandler.
extension=

If another PHP statement or expression causes a warning message or notice being printeded 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);
set_error_handler("var_dump");

Speaking of redirect headers, you should often use an idiom like this for final code paths:

exit(header("Location: /finished.html"));

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

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.

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.

You can always use headers_sent() to probe if it's still possible to... send headers. Which is useful to conditionally print an 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"));
}

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

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

  • And of course many specific cases have been covered on Stack Overflow as well.

White space before <?php and after ?> was my problem. Be careful about them!!

  • One of the more thorough explanations is HTTP Headers and the PHP header() Function - A tutorial by NicholasSolutions (Internet Archive link). It covers HTTP in detail and gives a few guidelines for rewriting scripts.

Also regular notepad.exe is tricky. I use NetBeans normally that doesn't add BOM, even if file is encoded so. Editing a file later in notepad messes things up, especially towards IIS as webserver. It seems as apache discards the (unitentionally added) BOM.

Removing the closing ?> from the end of a php files is usually a good practice which helps minimizing these errors as well. Unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.

Strange thing, I moved my file from cPanel Linux Hosting to VPS. Before it was working properly but here it showed this error.(I had some html code before header). Why?

But it worked on the other server!?

How to fix "Headers already sent" error in PHP - Stack Overflow

php header
Rectangle 27 2501

How can you find out where the premature output occured?

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

Some functions modifying the HTTP header are:

header
header_remove
session_start
session_regenerate_id
setcookie
setrawcookie
  • Whitespace before <?php or after ?>
<html>
<?php

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

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.

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.

print
echo
printf
vprintf
trigger_error
ob_flush
ob_end_flush
var_dump
print_r
readfile
passthru
flush
imagepng
imagejpeg

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.

  • The actual output logic and intermixed HTML output should follow last.

If the warning refers to output in line 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 which 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 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 sane 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 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.

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.

  • It's occasionally the gzip stream encoding setting or the ob_gzhandler.
extension=

If another PHP statement or expression causes a warning message or notice being printeded 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);
set_error_handler("var_dump");

Speaking of redirect headers, you should often use an idiom like this for final code paths:

exit(header("Location: /finished.html"));

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

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.

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.

You can always use headers_sent() to probe if it's still possible to... send headers. Which is useful to conditionally print an 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"));
}

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

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

  • And of course many specific cases have been covered on Stack Overflow as well.
  • One of the more thorough explanations is HTTP Headers and the PHP header() Function - A tutorial by NicholasSolutions (Internet Archive link). It covers HTTP in detail and gives a few guidelines for rewriting scripts.

Also regular notepad.exe is tricky. I use NetBeans normally that doesn't add BOM, even if file is encoded so. Editing a file later in notepad messes things up, especially towards IIS as webserver. It seems as apache discards the (unitentionally added) BOM.

Removing the closing ?> from the end of a php files is usually a good practice which helps minimizing these errors as well. Unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.

Strange thing, I moved my file from cPanel Linux Hosting to VPS. Before it was working properly but here it showed this error.(I had some html code before header). Why?

But it worked on the other server!?

How to fix "Headers already sent" error in PHP - Stack Overflow

php header