I have a script that has a call to header(); and its working fine for a couple of days since I first started running the script.
then after a couple of days, it started to have an error saying it cannot modify header information.
Then I put ob_start(); and ob_end_flush(); upon googling the error and it works!
The error has gone but my question is that why it works without ob_start(); and ob_end_flush(); for a couple of days before?
I want to know the explanation behind this behavior.
btw, I call header() this way:
if(condition is true){
header('Location: anotherpage.php');
}
and I have a session_start(); at the beginning.
Previously, you had no non-header output before the header line. Now, you have non-header output before the header line. That will only work if the output is buffered so the header can be actually output ahead of it.
You can not output any data before a header!
ob_start() is a output buffer and will buffer all echoed data and print it after all headers etc.
PHP flushes the data when the script is finished automatically so there's no need of the "ob_end_flush()"
You have some code outputting something before header() is called. It can be a print, echo or similiar statement, or even a white space before <?php.
The reason why ob_start causes the error to go away is because it causes any output to be buffered, therefore defered until the moment you call ob_flush.
This way it's guaranteed that the headers will come before content, even if you mess with the order of the commands in the code.
Related
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.
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
The php documentation suggests that I should end each ob_start() with an ob_end_flush(). I am using one on each page of a site, just to allow me to use firephp log methods anywhere in the app.
the app works fine, but I wonder if there is anything I don't know that might be detrimental.
I think the reason for this suggestion is, that PHP flushes your output buffer implicitly when not using one of the ob_end_* functions. While not an error, this can cause problems when not expecting it. The PHP-docs try to protect you from these kind of problems. If you are aware of the implicit flush, it is probably not an issue.
You can use Output Buffering as
<?php
ob_start();
echo "Some text you want to echo on page!!";
header("Location:somepage.php");
ob_end_flush();
?>
The problem is that we cannot send the header after we start sending the output. To solve this we buffer the output. The function ob_start turns output buffering on. While output buffering is active no output is sent from the script (other than headers), instead the output is stored in an internal buffer. So the echo output will be buffered. Next we send the header without any problem as we've not yet spit out any output. Finally we call ob_end_flush to flush the internal buffer contents and to stop output buffering.
if there is loops, for example, some one can start buffering. And calls your function. When he tries to ob_end_flush code gathers your contents.
I appeared for php test, their I was asked one question for which I could not find the answer.
The question is like this.
echo "MESSI is injured!!";
header("Location:somepage.php");
Interviewer want both header and echo to be written on the same page.
I wonder how's it possible.It should give some error like
headers already sent by (output started at .....
Is it really possible to write echo and header onto same page !!!
You can use Output Buffering as
ob_start();
echo "MESSI is injured!!";
header("Location:somepage.php");
ob_end_flush();
The problem is that we cannot send the header after we start sending the output. To solve this we buffer the output. The function ob_start turns output buffering on. While output buffering is active no output is sent from the script (other than headers), instead the output is stored in an internal buffer. So the echo output will be buffered. Next we send the header without any problem as we've not yet spit out any output. Finally we call ob_end_flush to flush the internal buffer contents and to stop output buffering.
You can do it as long as all the header calls come before any non-header output is sent (this includes pesky things like newlines/whitespace). So
<?php
header("Location:somepage.php");
echo "MESSI is injured!!";
?>
should do the trick
I'm using set_cookie() on a site. After adding some functionality, I'm getting Warning: Cannot modify header information - headers already sent by... error. The line number it references as to where the headers initiated from is the very line where set_cookie() is! And I checked, it's not being called twice.
How can I track down these premature headers? I looked at the source code and didn't see any stray characters or anything before the error message starts ( I'm using xdebug, so the first thing is a , which I thought was me, but is actually the beginning of the xdebug message ). I've grepped my code for extra echo and so forth -- nothing.
Can PHP tell me when and where the headers are starting? Or are they really starting on the set_cookie line, and if so, how have I gotten myself into this situation, and how do I get out?
edit: I'm not sure I can paste the code -- do you want just the set_cookie() line? I thought the headers were coming out before that. And there's a lot going on before that with different classes being instantiated. And also I don't think I can post all the classes and stuff -- you know, proprietary information ;)
Edit: I've gotten rid of all terminating delimiters ( all ?>s) and made sure that the first characters of every included file is <?. This is frustrating! It was working before I did these recent changes :(((
Also, why doesn't headers_sent() work?
if ( headers_sent($filename, $linenum) ) {
echo "headers sent: $filename:$linenum.";
}
set_cookie(...);
gives
headers sent: :0.
You can use headers_sent():
if (!headers_sent($filename, $linenum)) {
set_cookie(/*...*/);
} else {
echo "Headers already sent in $filename on line $linenum\n";
exit;
}
One approach would be to run your script from the command line with STDERR redirected to null.
This will show you everything that is being sent to STDOUT, i.e. everything that the server would send to a client.
Hopefully, once you see this, it will be clear where your headers are coming from.
Besides using headers_sent to detect if the HTTP header has already been sent, you could use the PHP’s output control to buffer the output. That allows you to change the header even if you’ve already done some output.
Here’s some example using the explicit output buffering by calling ob_start:
ob_start();
echo 'foobar';
header('Content-Type: text/plain;charset=utf-8');
But make sure you call ob_start before any output was done. Otherwise the HTTP header probably has already been sent.
Can you paste the code?
If its saying headers already sent by [line where set_cookie is], then the error is further on in the script.
Are you sure that you don't have any include files being called prior to your set_cookie() initialization? Do you have sessions running, because if you do, you could just set the cookie at that same point in your script as you started the session.
If there is even a single white space before your set_cookie() initialization it will cause the headers to not be sent correctly. Maybe try using a different editor and checking your results.
I found it! It was a flush(); that I had left lying around all by itself in one of the pages. Surprisingly, it doesn't correctly bind $filename and $linenumber to headers_sent().