PHP Warning: headers already sent - Sessions/Cookies

Hi,

I am designing a basket for the web site. I am aware that sessions/cookies should be applied before the HTML tags. But I am still having problems!

I am using this code saved as cart.php:


<?php

// This page contains the connection routine for the
// database as well as getting the ID of the cart, etc

$server = "location";
$user = "usernamet";
$pass = "passwordhere";
$name = "Database";


// Connect to the database and return
// true/false depending on whether or
// not a connection could be made.

$connect = @mysql_connect($server, $user, $pass);
$d = @mysql_select_db($name, $connect);

if(!$connect || !$name){
return false;}
else{
return true;
}

function GetCartId()
{
// This function will generate an encrypted string and
// will set it as a cookie using set_cookie. This will
// also be used as the cookieId field in the cart table

if(isset($_COOKIE["id"]))
{
return $_COOKIE["id"];
}
else
{
// There is no cookie set. We will set the cookie
// and return the value of the users session ID

session_start();
setcookie("id", session_id(), time() + ((3600 * 24) * 4));
return session_id();
}
}
?>

And then I am using this code saved as showcart.php (the code is shortened here, since my problem is with the HEADERS.ALSO NOTICE THE <?php include(“cart.php”); AS THIS IS LIKELY SOMETHING TO DO WITH MY PROBLEM:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?php include("cart.php"); 
$connect = @mysql_connect($server, $user, $pass);
$d = @mysql_select_db($name, $connect);
$result = mysql_query("select * from cart inner join items on cart.itemId = items.itemId where cart.cookieId = '" . GetCartId() . "' order by items.itemName asc");

//Once the list of items is retrieved, each item is displayed as part of a table, as a table row:

while($row = mysql_fetch_array($result))
{
// Increment the total cost of all items
$totalCost += ($row["qty"] * $row["itemPrice"]);?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
</head>

<body>
<tr>
<td width="15%" height="25">
<font face="verdana" size="1" color="black">
<select name="<?php echo $row["itemId"]; ?>" onChange="UpdateQty(this)">
<?php

for($i = 1; $i <= 20; $i++)
{
echo "<option ";
if($row["qty"] == $i)
{
echo " SELECTED ";
}
echo ">" . $i . "</option>";
}
?>

As far as I can see, the Sessions/Cookies are above the HTML tag. But I get these messages:


Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at /home/content/LOCATION/html/showcart.php:2) in /home/content/LOCATION/html/cart.php on line 40

Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at /home/content/LOCATION/html/showcart.php:2) in /home/content/LOCATION/html/cart.php on line 40

Warning: Cannot modify header information - headers already sent by (output started at /home/content/LOCATION/html/showcart.php:2) in /home/content/LOCATION/html/cart.php on line 41

Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /home/content/LOCATION/html/showcart.php on line 9
//As I mentioned above, the quantity for each item is displayed in a drop down list. This list is generated with the following code:

LINES 40 and 41 are referring to the first bit of code above:
LINE40 session_start();
LINE41 setcookie(“id”, session_id(), time() + ((3600 * 24) * 4));

So I am puzzled?! This file does not even have a HTML tag! I thought the WARNING might be coming from the ShowCart.php page but it does refer to lines 40 and 41 in the cart.php page. Not sure how they talk to each other!?

Matt.

I am aware that sessions/cookies should be applied before the HTML tags.

session_start should be applied before any output. The best way to prevent that error is to put session_start at the very first line of the script.

And in this case there is a line of output before you include cart.php

Can please ensure you place tag around your code in future, thanks!

I thought I did place a tag - I’ll check again next time.

As suggested I added the include before the first line of code and it is now working. But there is no cookie on my computer and I think that is why the rest of the coding is not working either. Any ideas why a cookies is not appearing in my computer!?! My coding checks to see if the cookieid matches that on my computer but if there is not one there it is not very helpful.

Matt.

In addition to cookies not appearing…

this code might be wrong. Can a switch define cases and then afterwards define the functions to use??:


<?php include("cart.php");?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
</head>

<body>
<?php
switch($_GET["action"])
{
case "add_item":
{
AddItem($_GET["id"], $_GET["quantity"]);
ShowCart();
break;
}
case "update_item":
{
UpdateItem($_GET["id"], $_GET["quantity"]);
ShowCart();
break;
}
case "remove_item":
{
RemoveItem($_GET["id"]);
ShowCart();
break;
}
default:
{
ShowCart();
}
}

//Looking at the switch statement above, we have four possible cases, each of which is discussed below:
//add_item: When the user clicks on the "Add Item" for an item on the products.php page, this case will be called. It calls //the AddItem function, passing in an items ID and quantity.
//update_item: Updates the quantity of an item in the users shopping cart. As you will see shortly, each item in the cart 
//is displayed with a drop down list, that, when changed, automatically updates the numeric of a specific item in the users //shopping cart.
//remove_item: Deletes an item from the cart table for the current user.
//If the cart.php page is called up with no query string parameters, then the ShowCart function is called. Let's start by //looking at the AddItem function.

//AddItem accepts two parameters: The ID of the item to add to the cart, and the number of that item to add:

function AddItem($productid, $quantity){

//The main part of the AddItem function checks whether or not this item already exists in the users cart. If it does, then //its quantity field is updated and it isn't added again:

$result = mysql_query("select count(*) from cart where cookieid = '" . GetCartId() . "' and productid = $productid");

$row = mysql_fetch_row($result);
$numRows = $row[0];

if($numRows == 0)
{
// This item doesn't exist in the users cart,
// we will add it with an insert query

@mysql_query("insert into cart(cookieid, productid, quantity) values('" . GetCartId() . "', $productid, $quantity)");
}
else
{
}

// This item already exists in the users cart,
// we will update it instead

UpdateItem($productid, $quantity);
}

//Looking at the code above, we can see that if $numRows equals zero (i.e. the item isn't already in the users cart) then //the item is added to the cart table. If not, the items quantity field is updated by calling the UpdateItem function, 
//which is described below.

//UpdateItem accepts two parameters, in the same way that the AddItem function does:

function UpdateItem($productid, $quantity){

//It executes a simple UPDATE SQL query against the cart table, updating the quantity of one specific item. The cookieId //field is used to match the users session ID to that particular product, making sure that the quantity is only updated for //that item and the current user:

mysql_query("update cart set quantity = $quantity where cookieid = '" . GetCartId() . "' and productid = $productid");

//Removing an item is a simple matter of the RemoveItem function being called. It accepts just one parameter, which is the //ID of the item to delete:
}
function RemoveItem($productid){

//Once connected to the database, a simple SQL DELETE query removes the item from the current users cart:

mysql_query("delete from cart where cookieid = '" . GetCartId() . "' and productid = $productid");

//All of these functions are good, but to actually call them, we need to look at the ShowCart function, which is what we //will do on the next page.
}
?>
</body>
</html>

I think the cookies not appearing on the computer is the main problem but I need to know if I am using the switch correctly but defining the function after the case.

Matt.

P.S. I used tags in this post but it does not seems to recognise them - am I doing something wrong when posting?

P.S. I used tags in this post but it does not seems to recognise them - am I doing something wrong when posting?

What tags are you using?
If you use ‘post reply’ instead of the quick reply box, you’ll see all tag buttons in the editors menu bar above the text box.

Just type [noparse]

 ... code ... 

[/noparse] around your code Matt. :slight_smile:

[noparse]


[/noparse] is better. Note that the php tags will mess up if you post PHP 5.3 code involving namespaces since the \ character gets striped incorrectly by the php bbcode for some reason.

To the OP’s question – You must make sure that there is no whitespace at all before the opening <?php tag. Also, unless you need it, do not use a ?> at the end of the file because some IDE’s and repositories will put a new line character at the end of a file that doesn’t end with a new line which spells trouble.

The reason for this is all headers must be sent before any other content. The session key is sent as a cookie as part of the headers - this is the reason the session cannot be started after headers are sent.

OK - the warnings are resolved now but there is still no cookie on my computer. I am thinking there is no where in the code asking for the function for the cookie to be produced to be executed…

I think the first calling relating to the cookie is in this bit of code with the ShowCart.php:

$result = mysql_query("select * from cart inner join items on cart.itemId = items.itemId where cart.cookieId = '" . GetCartId() . "' order by items.itemName asc");

Surely, there will be no cookie, as the function has not be asked to run?

Even this bit of code in the CartAction.php does not ask for the function to be run:

$result = mysql_query("select count(*) from cart where cookieid = '" . GetCartId() . "' and productid = $productid");

$row = mysql_fetch_row($result);
$numRows = $row[0];

if($numRows == 0)
{
// This item doesn't exist in the users cart,
// we will add it with an insert query

@mysql_query("insert into cart(cookieid, productid, quantity) values('" . GetCartId() . "', $productid, $quantity)");
}
else
{
}

// This item already exists in the users cart,
// we will update it instead

UpdateItem($productid, $quantity);
}

It does not make sense to use a value that has not been established. Maybe I am wrong—I am new to this.

This is the code: http://www.devarticles.com/c/a/MySQL/Building-A-Persistent-Shopping-Cart-With-PHP-and-MySQL/1/ - some of it needs completing as I have done (tried to do)

Hope you can help,

Matt.