views:

89

answers:

7

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. 
+7  A: 

You can use headers_sent():

if (!headers_sent($filename, $linenum)) {
    set_cookie(/*...*/);
} else {
    echo "Headers already sent in $filename on line $linenum\n";
    exit;
}
Stefan Gehrig
Right before `set_cookie()`, `if ( headers_sent($filename, $linenum) ) { echo "headers sent: filename:$linenum."; }` gives `headers sent: :0.` :(
Please make sure (as others suggested) that there is no character (even a whitespace or a BOM) before you `<?php` sequence and none after your `?>` in all of your included PHP files.
Stefan Gehrig
A: 

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.

Josh
+2  A: 

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.

Dancrumb
Thank, Dan. How do I do the redirection? The actual chain of events depends on POST submissions, so I'm not sure I could even trigger it on the command line anyway.
A: 

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.

Joe Majewski
A: 

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.

Joe Majewski
What editor would you recommend?
I use Zend Development Environment (http://www.zend.com/en/)
Joe Majewski
+1  A: 

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.

Gumbo
A: 

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