picture of Evert Smith

Introduction

If you haven't done your own shopping basket with PHP yet, you should be able to build one after reading this article. Even if you have a basket already, some of the tips I provide here could help you improve your system.
I will give you some hints about how you could perhaps save yourself endless queries to the basket table or having endless text files that fill up your file system, because the application just does not remove them.
If you're new to this sort of topic, don't be scared. It is actually very simple and effective, all you need is a host that supports php4, some html editor like notepad or vi, some minutes of your precious time, and this little example.

The Idea

In 1998 a friend of mine working at a hardware store asked me to code an online shop for them. It needed to be fast and simple, with online administration. I get rather creative when running a 39deg Celsius fever, so I wrote that thing in perl, using minisql as a backend. During the process I put in what I refer to as a minibasket.
This minibasket is just a smaller variant of the regular shopping cart, showing you the contents of your cart on each page, without you having to jump back and forth to the cart after you've put an item into it. That's the idea I picked up for this article.

The Goal

People like control, so why not give them transparency and let them believe they have control? This minibasket is a perfect way of providing people with the needed information and also saving them 1 click, getting closer to the 3-click paradigm for online shops.
So, the goal is to show this minibasket on a part of your page at all times, a summary at the end to modify the items in your basket and finally to send of an order.

The Requirements

You should know about sessions. If not, here a quick rundown. There are many articles about it already, to find all the examples of code you need. Open a session on your start page with:

<?php

session_start
();

?>
This will create a session name and a session id. You now either use the default by setting session based cookies, pass the session id on with post through a form or attach it as variable to your link (get-method). Don't forget to destroy the session at the end. :)
Your articles should have a name and price and a unique identifier to work with this example, if not, you may want to modify it a bit. I used mysql for backend here, to build the pages etc, this is not required for the basket to work though. :)
You should know about arrays. Now if someone has the time to take my code and create a class of it, I'd certainly appreciate to have it.:)

The Definitions

For the simplicity of this example I am using four separate arrays and some additional variables. The code can be optimized. This makes it easier to display the idea and to read the code. This could be done better with a class, but I am not quite sure if you can store objects into sessions. Someone comment on this?
We also need an item counter. Of course this could be done with the count() command, I just thought it would be nice to always know how many items there are, and it gives a nice counter for loops too.

The Works

Let's assume you have a listing of articles in your html page:
ID Name Price
1 Mouse 25.00 add
2 Key 100.00 add
3 Car 5000.00 add
4 Game 25.00 add

 
Adding the Link to Your Page
The 'add' field is the link to place items into the mini basket. Point this link to itself using the $PHP_SELF variable. Then add the article information to it. Here's the example for article 1.
<A HREF="<?echo $PHP_SELF;?>?id=1&price=25&basket=Mouse">add</A>
Article Names can contain spaces, so put it at the last position in your link. The get method seems to be picky about this.

 
Preparing the Minibasket
For reusability, lets create an external file minibasket.inc. I use the .inc extension to mark my include files. The reason to put this external is, even though you will be passing the basket on using session variables, the code still needs to be available.
The file will contain the code to display the mini basket, and the function to add items to it. Best place to implement this is to put the:
<?php include ("minibasket.inc"); ?>
command right there where you need it.

 
The Logic of the Minibasket.inc
Spend some time thinking about this. What should the minibasket look like, what features does it need? The minibasket displayed here would look something like this:
#NamePrice
1 Mouse 25.00
3 Game 75.00
Total 100.00
You can easily format this output using an external style sheet. It should not be too big, though. This minibasket is information, yet it is not the focus of the page you are showing.
The logic of the file is very simple.
Check if a new item needs to be added.
If true, add the item.
Within the adding it looks for duplicate entries and updates the existing entry by updating amount and pricing information.
Snippet 1: Checking for new item to be added
This is a regular IF Statement looking for the value of the variable $basket.

<?php

if ($basket!=""){
    
//add item to basket.
}

?>
Snippet 2: Printing the basket to the browser

<?php

if ($ses_basket_items>0){
    
// If there are items in your basket
    
for ($basket_counter=0;$basket_counter<$ses_basket_items;$basket_counter++){
            
// Go through the basket and print out each line
            // You can of course format this to be in a table
            // The formatting is needed to display the cents of your order. .00 will not display
            // if not formatted .
            
$price=sprintf("%01.2f",$ses_basket_price[$basket_counter]);
            
$amount=$ses_basket_amount[$basket_counter];
            
$name=$ses_basket_name[$basket_counter];
        echo 
"$amount $name $price";
        echo 
"<BR>\n";
    }
} else {
    
// there are no articles in your basket
    // setting the item counter to 0 and unsetting all variables
    // This is a clean up here. It prevents people from getting old arrays back.
    
$ses_basket_items=0;
    unset(
$ses_basket_name);
    unset(
$ses_basket_amount);
    unset(
$ses_basket_price);
    unset(
$ses_basket_id);
}

?>
The result of this piece of code equals nothing. The items are not filled, the basket always empty and therefore the basket never displayed. So let's add some items to this basket.
Snippet 3: Starting a new basket and add 1 item to it

<?php

// Put the item counter to 1
$ses_basket_items=1;

// Fill the 4 arrays at position 0 with the values from the href link
// shown in the 'adding the link to your page' part
$ses_basket_name[0]=$basket;
$ses_basket_amount[0]=1;
$ses_basket_price[0]=$price;
$ses_basket_id[0]=$id;

// register the new basket in the session
session_register("ses_basket_items");
session_register("ses_basket_name");
session_register("ses_basket_amount");
session_register("ses_basket_price");
session_register("ses_basket_id");

?>
This will start the basket, fill all values at position 0 of the arrays and register the arrays with the session. A basket is born!
Snippet 4. Filling the basket

<?php

$basket_position_counter
=0//Position in basket
$double=0//Flag for double entries set to NO
if ($ses_basket_items>0){
     
// If the basket contains items check for double entries
     
foreach ($ses_basket_name as $basket_item){
            
// Run through the array that contains the name and
            // check if it matches the item from the href.
            
if ($basket_item==$basket){
                 
// Set Flag to 1 if the item is already in the basket.
                 
$double=1;
                 
// Remember the position of the item to be updated
                 
$basket_position=$basket_position_counter;
            }
            
$basket_position_counter++; //Increment actual Position in basket
     
}
}

// Update the basket        
if ($double==1){
     
// Update amount and price at position $basket_position
     // if the item is already in your basket
     
$oldamount=$ses_basket_amount[$basket_position];
     
$ses_basket_amount[$basket_position]++;
     
$amount=$ses_basket_amount[$basket_position];
     
$oldprice=$ses_basket_price[$basket_position];
     
//update the price
     
$newprice=($oldprice/$oldamount)*$amount;
     
$ses_basket_price[$basket_position]=$newprice;
}else{
     
// Add new item at end of array
     // if it is not in your basket
     
$ses_basket_name[]=$basket;
     
$ses_basket_amount[]=1;
     
$ses_basket_price[]=$price;
     
$ses_basket_id[]=$id;
     
$ses_basket_items++;
}

?>
Great, now you can fill the minibasket and display it.
Putting the Snippets Together
Lets put the code together and store it as minibasket.inc

<?php

// remember the code from Snipplet 1, deciding whether to add or not?
// Let's repeat it here
if ($basket!=""){
     
//In here items will be added to the basket. let's check if there is already
     //a basket registered.
     
if (session_is_registered("ses_basket_items")){
            
// There is a registered basket
            // Place Snipplet 4 here. It adds the item to the registered basket, checks
            // for duplicate entries, updates them or adds the item at the end of the
            // arrays.
     
} else {
            
// There is no basket registered
            // Place Snipplet 3 here. It creates a new basket and registers it with
            // the session.
     
}
}
// All there is left is Snipplet 2. It displays the basket if there are items in it.
// Add it here.

?>
Et voila. "c'est tout", as the French would say. If all is done right, you can store this file as minibasket.inc and include it into your PHP Page where you're showing the articles.
-- Evert