PHP output_buffering on/off issue - php

I have created a PHP application with output_buffering = On.
Now, if i do output_buffering = Off then i have get following error
"Cannot modify header information - headers already sent by ".
How can i remove this error?
What can be the drawback if i upload application on live site with output_buffering = Off?

From PHP Tag Wiki:
Q. "Headers have already been sent..."
A. You're outputting content and triggering PHP's default content-type:text/html header before making your own call to header(). There are a few ways this can happen, check for a stray echo or print, whitespace before and after the tags or maybe a Unicode BOM. Consider using output buffering. With many scripts, there is no need to include the ending ?> and the problem is easily fixed by removing the ending ?> tag from your files.
There is also a myriad of duplicates for this.

Send out your headers before any output goes to the browser.
header('Foo: bar');
echo "foo";

If you turn output buffering off, you are not allowed to send any additional headers (this includes cookies e.g.) after you've send any piece of data to the client (namely using echo or some other output function).
You can use headers_sent() to check where you started to output data to the client.

Ensure all header('') tags go right at the top of the script with no white space!
EG:
<?php
header('type of header');
?>
If you really have to do it further down the page you can call ob_start() at the top of the script. Call ob_end_flush() at the end of the script too.

Related

Call header() after output is sent

According to the PHP documentation:
header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP. It is a very common error to read code with include, or require, functions, or another file access function, and have spaces or empty lines that are output before header() is called. The same problem exists when using a single PHP/HTML file.
but when I tried the example that the documentation reports (with a little change):
<html>
<?php
/* This will give an error. Note the output
* above, which is before the header() call */
header('X-Header: http://www.example.com/');
exit;
?>
all worked just fine, no error poped up and I smoothly got my <html> tag in the output and my X-Header in the headers.
I'm using PHP 7.1.9, so is still correct what the documentation says?
The documentation is still correct.
For performance purposes, the interpreter puts the output in a buffer. When the buffer is filled for the first time, the interpreter sends the headers then it sends the content of the buffer (and empties the buffer). After this point any call of the function header() fails. The headers cannot be modified any more and other headers cannot be added because the headers have already been sent.
This lets the script produce a small amount of output before sending the headers.
Read more about output buffering configuration settings.
The option output_buffering allows turning the feature off or on and even setting the size of the buffer.
The option implicit_flush tells the interpreter to flush the buffer after every output block. This forces your script to send the headers correctly, before any output.
edit your php.ini and enable Output Buffering ..

Alternative to <?php ob_start(); ?> ..<?php ob_flush(); ?>

Is there any alternative available to
<?php ob_start(); ?>
Codes go here..........
<?php ob_flush(); ?>
for eliminating Warning: Cannot modify header information - headers already sent by (output started at............
I'm looking for an alternative .htaccess rewrite rule to the above PHP functions.
Thanks,
You will be unable to fix that error by editing your htaccess file unless you hide the error which won't fix your actual issue because the header change that you attempted will fail.
Instead, you need to ensure that you modify the headers before you output any html, text or white space. This error can often be caused by:
white space before your opening php tag
outputting some html (such as the docytpe and head) then attempting to change the location header to redirect to another page
The true "alternative" (which really isn't an alternative, but is instead the right way) is structuring your code so that no header is set after the output has started.
There is really no case when this is not possible, and output buffering is not meant to be used as a workaround for this.
An alternative and simple resolution to this problem is to enable output_buffering variable on the PHP server which can be easily done by saving the following code in php.ini file.
output_buffering = On

how to ignore redirection errors in php

I got this warning in php:
Cannot modify header information - headers already sent by (output started at
When I installed mysql, apache, and php separately but when I'm using Wamp the warning does not exist and the page redirects gracefully.
I have already tried setting the error reporting to only display errors and not warnings and what happened is that the warning didn't show up but the page also didn't redirect.
I know this is already considered bad practice but my code base has a lot of these codes and modifying them all might introduce new bugs to the code.
Is there any way to completely ignore this warning in php?
The classic way to avoid - and not ignore - this problem is with output buffering, ob_start() and ob_flush(). Start the buffering before any output, and finish with the flush explicitly, or it may do so automatically. This captures any output rather than printing it, and so any headers that are output are done so before any visible content.
Fixing the bug of things being output, from the filename you had in the error message is the best way to fix this though. Removing the closing '?>' from files when it's not needed might help.
This is an horrible practice but just set
error_reporting(0);
at the beginning of your script. Otherwise setit in php.ini
display_errors = Off
EDIT - probably you are outputting something before the redirect. I once spent three days debugging this and the reason sometimes is whitespace at the end of files or the fact that you output some HTML to the browser before the redirect.
I usually never close the php tag to avoid this
Even when you don't show your error your application will not work. This is because like the error said the headers are already sent. What this means is the following:
A browser requests your php file at the server. The server then executes this and sends back the resulting html. This error tells you that you are sending something back to the browser after you already sent the result of your php file. So I'd suggest you try to fix the error your getting instead of just not showing it.
You can't "ignore" this warning and redirect. The warning says so clearly:
Can't send headers! Headers already send by output!
This means that the header (the Location header cannot be sent because output was already sent. (Headers may only be sent before any and all output).
Please RTM, you need to fix your bugs, not ignore them.
The error is caused by you sending some sort of output before the header() function is called, the reason for that may be a lot of things, when unexpected, the immediate suspect is a whitespace at the beginning or ending of some file.
<?php //Note the space before the opening tag!
header("Location: this-will-fail.html");
?>
Please note that this error specifies exactly where in your code you've started to output data to the browser (see the output started at ...1, look for trailing white space \r, \n, tabs & spaces).
In theory, turning off the error reporting will not cause the page to redirect because the headers were already sent and therefore cannot be changed or added to.
What you should do if you need to redirect with data already sent is something like this:
if ( headers_sent() ) // Check if the headers were already sent
{
echo( "<script>document.location.href='$url';</script>" ); // Use client side redirect
die(); // Stop here
}
else
{
header( "Location: $url" ); // Use server side redirect
}
But the best thing would be to find out where the output started and fixing that (if possible).

alternate php redirection method that works with output preceding it

so apparently if you do this:
<?php
echo 'something';
header("Location: http://something/");
?>
it will not work because there is an output preceding the header...
is there any other alternative php redirection method that works straight from php without installing anything and in which it will still work even if there's an output preceding it so that I don't have to worry about making sure that there is no output before, etc...
not, unless you do something in javascript or html tags in the page that you output itself
if preceding output is a problem
you can also use output buffering, see ob_start, ob_get
to get around that
There is no other way to do a php redirect, but you can fool it to still work even with code prior. You would buffer the content and only output it if there is no redirect or reaches the end of the script. Note: this may be resource heavy in some cases.
ob_start()
....CONTENT...
ob_end_flush();
There are no ways in PHP except using header()... before output is sent (headers be already sent)...
You can either use meta refresh in HTML that is set at zero seconds, or javascript.
But I wouldn't recommend javascript as some will have it disabled.
You could use a meta refresh tag.
You understand why this is impossible, right?
As soon as you echo "something" you have sent content to the client, and as part of that client headers were already sent. You can't retroactively modify headers you already sent, and you can't make two responses to one HTTP request.
ob_start() and ob_end_flush() will buffer the output instead of sending it to the client, which will allow you to get around this problem, BUT
a better solution would be to:
separate your logic code from your template so that you don't write anything to the screen until you already know you aren't going to redirect.

PHP redirect without header() or meta

I'm trying to design a page which does some database actions, then redirects to user back to the page they came from. The problem is that I use a require() function to get the connection to the database, so the headers are already sent. A meta tag is out of the question since I want it to look like all the processes are done from the page they came from. Any tips? Is there a way I can use the require() and the header() or do I have to drop one? Is there an alternative to header()?
If you can't send the header() before some content gets sent, use output buffering by placing an ob_start(); at the beginning of your script before anything is sent. That way, any content will be stored in a buffer and won't be sent until the end of the script or when you manually send the buffer's contents.
On another note, simply requireing another file would not generate any headers/content unless that included script sends them. The most common "hidden" cause of this is unnoticed whitespace before or after the <?php ?> tags.
As Artefacto noted, connecting to the database should not require any output. Fix whatever you're including (e.g. database_connect.php) not to output. See this search on the "headers already sent" issue, which may help you find "hidden" output.
ob_start(); // start output buffering
echo "<html......"; // You can even output some content, it will still work.
.
.
.
.
.
header("Location: mypage.php");
ob_flush(); //flush the buffer
In this case, all output is buffered. This means, the headers are processed first, then the output comes to play...
You cannot send any headers after some content has already been sent. Move the header() call to be before the require() call.
You cannot send headers after any data has been sent to the client.
However, using require does not meen that you output something. If i understand your right, you can include your database files, run your queries and then redirect the user. This is perfectly valid.
If you need to send some output (why if you need to do a redirect?) another option is to use output buffering. By using output buffering, you're not sending the data to the browser when you echo it, but you store it in a buffer. The data will be sent when you call ob_end_flush or you reach the end of the script. After ob_end_flush, you won't be able to send any new headers. You start output buffering with ob_start.
It is possible to use header() with require() when I use output buffering. That means that the whole script is buffered and first send when the script has come to an end.
I have done it by doing this
ob_start("ob_gzhandler"); //begin buffering the output
require_once('/classes/mysql.php');
// Some code where I access the database.
header('/somepage.php');
exit;
ob_flush(); //output the data in the buffer

Categories