php - track down premature headers leak
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 extraecho
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 insta开发者_JS百科ntiated. 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()
.
精彩评论