Dealing with cannot modify header errors

by Eric Gach
Tuesday, 6th September 2005

Overview

Ever have that problem when you goto set a cookie, or start a session, or even do a redirect and you get the error "Warning: session_start(): Cannot send session cookie - headers already sent by (output started at /home/eric/www/test.php:2) in /home/eric/www/test.php on line 3"?

Well, I know I have, and I know this is kinda confusing when you're first starting out in the lanuage. So let's begin by explaining what this is telling us.

What all of these errors are trying to tell you is that some form of data is being sent to the browser before you made a call to that function. This data can be anything from HTML before your PHP code, to an echo in your PHP code before that function call, to a simple whitespace at the beginning of the file. I'll elaborate on the next page.

Examples

OK, so say we're calling the setcookie() function and we're getting that stupid "Warning: setcookie(): Cannot send cookie - headers already sent by (output started at /home/eric/www/test.php:2) in /home/eric/www/test.php on line 3" error. Well, let's take a look at this...

First off, we have the HTML method:

<html>
<head>
<title>My wonderful page!</title>
</head>
<body>
<?php
//Let's set a cookie to remember the user
setcookie('remember', $_SERVER['REMOTE_ADDR'], time() +3600);
?>
<h1>Welcome to my site!</h1>
</body>
</html>

Now, we see here that there is HTML way before the setcookie() function is even called. This is bad. That's what's giving us the error in this example. To fix this code, all we really need to do is move the setcookie() function call above the HTML like so:

<?php
//Let's set a cookie to remember the user
setcookie('remember', $_SERVER['REMOTE_ADDR'], time() +3600);
?>
<html>
<head>
<title>My wonderful page!</title>
</head>
<body> 
<h1>Welcome to my site!</h1>
</body>
</html> 

Now by doing this, it will send the cookie before anything else is shown to the browser. Another common problem is an echo or some sort of output function before the setcookie() function call such as:

<?php
//Tell the user we're going to remember them
echo 'I'm remembering you!';
setcookie('
remember', $_SERVER['REMOTE_ADDR'], time() +3600);
?>
<html>
<head>
<title>My wonderful page!</title>
</head>
<body> 
<h1>Welcome to my site!</h1>
</body>
</html> 

In this example, we did good by keeping the HTML all after the setcookie() function call, but there's still that echo right before the setcookie() call. Oops. This will cause the same error as the HTML before the setcookie() call because it's still data being sent to the browser. This is also true with print and other output functions. So, to simply fix this, we do this:

<?php
//Tell the user we're going to remember them
setcookie('remember', $_SERVER['REMOTE_ADDR'], time() +3600);
echo
'I'm remembering you!';
?>
<html>
<head>
<title>My wonderful page!</title>
</head>
<body> 
<h1>Welcome to my site!</h1>
</body>
</html> 

 Of course, I know you would want to put that echo in with the HTML, but hey, just trying to keep it simple. Besides, I know you're smarter than that. On to the next page for more examples!

More Examples

Just when we thought it couldn't get any funner... the common whitespace error! This happens when we have a whitespace or a newline before our PHP tags, even tho all of our echo's and all of our HTML is after the setcookie() we're still getting an error! Example:

<?php
//Tell the user we're going to remember them
setcookie('remember', $_SERVER['REMOTE_ADDR'], time() +3600);
echo
'I'm remembering you! (I did good, I put this after the cookie call :)';
?>
<html>
<head>
<title>My wonderful page!</title>
</head>
<body> 
<h1>Welcome to my site!</h1>
</body>
</html> 

Yes, you see that? Right there infront of the php tag, it's not really just a php tag, there is a whitspace right infront of it. This is bad, that little whitespace is considered text just like the HTML was and is sent to the browser before the setcookie() function. Bad code monkey!

So just fix that by removing that nice little space, and all will be well. Now I know some of you have gotten the "included file" error, and this one can be annoying and confusing.

Here's a sample error of what I'm talking about "Warning: Cannot modify header information - headers already sent by (output started at /home/eric/www/echo.php:2) in /home/eric/www/test.php on line 3"

Now this error gets some people, they go looking at test.php for output and can't find any. The real error is in the included file echo.php. Let's take a look and see what I just did here. This is the test.php file.

<?php
include_once('/home/eric/www/echo.php');
setcookie('blah', 'foo');
echo
'test';
?>
This is the echo.php file. <?php
echo 'blah';
?>

Now, what we see here is that test.php includes echo.php, sets a cookie, then echo's data out to the user. However, when we include echo.php that file is executed. This is what gives us our error because echo.php is executed when it is included and the echo 'blah'; is outputted to the browser before the setcookie() function. To fix this, there's a couple ways to do it... let me show you on the next page.

Output Buffering

OK, so we have that big nasty error about not being able to modify headers... but how to get rid of it? There's a couple of ways acually. First off, we just change the include in test.php around so that it's after the setcookie() function like so:

<?php
setcookie
('blah', 'foo');
include_once(
'/home/eric/www/echo.php');
echo
'test';
?>

Simple enough, right? I thought so. Our second option is to start output buffering. It's not really all that hard at all, here's an example of test.php with output buffering:

<?php
ob_start
();
include_once(
'/home/eric/www/echo.php');
setcookie('blah', 'foo');
echo
'test';
$contents = ob_get_contents();
ob_end_clean();
echo
$contents;
?>

Now this doesn't throw us a nasty error. Why? Well, when ob_start() is called in a script, it allows all headers to be sent to the browser, but all HTML, output, whitespaces are held into a buffer until you get them or until the script ends. This is a pretty easy method of fixing the error so it's also an option.

Conclusion

Well... I hope this was informative as well as educational. If you would like more information on the output buffering functions, please see the PHP manual. Remember, this doesn't only apply to setcookie() these statements are also true (baring author error ;) to header(), session_start() and any other function that deals with headers you can think of. Well, it's been fun and hopefully helpful.

Happy Walrusing!


© 2005 Eric Gach
View the original article Dealing with cannot modify header errors