http://www.developer.com/

Back to article

Developing a Ajax-driven Shopping Cart with PHP and Prototype


January 25, 2007

In recent weeks I've been working on an e-commerce project. Among the project goals included building an Ajax-driven shopping cart which is intended to further enhance the user's shopping experience. In the latest installment of this ongoing PHP series, I'll show you how to build a shopping cart using PHP, session handling, and the Prototype JavaScript library (introduced in an earlier installment). The cart allows users to add and delete products from the cart, as well as change cart quantities. And of course, the interaction is seemingly instantaneous, allowing for the user to continue shopping without waiting for the page to reload.

A Sample Products Table

Although we won't integrate a database into the cart mechanism, as a matter of reference a simple products table might look like this:

CREATE TABLE products (
   id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
   title VARCHAR(50) NOT NULL,
   author VARCHAR(50) NOT NULL,
   price DECIMAL(4,2) NOT NULL,
   PRIMARY KEY (id)
);

Next let's add a few table rows:

INSERT INTO products VALUES(NULL,"Beginning PHP and MySQL 5, 2E",
    "W. Jason Gilmore", "44.99");
INSERT INTO products VALUES(NULL,"Beginning Ubuntu Linux ",
    "Keir Thomas", "39.99");
INSERT INTO products VALUES(NULL,"Pro MySQL",
    "Jay Pipes and Michael Kruckenberg", "49.99");

Creating the Shopping Cart

The easiest way to manage user shopping carts is through an array stored in a user session. This key represents the product id, and the value represents the count of that particular item found in the cart. Therefore if the user's shopping cart consisted of two copies of "Beginning PHP and MySQL 5", and 3 copies of "Pro MySQL", the array would look like this:

$cart[1] = 2;
$cart[3] = 3;

To manage this array, I've created a class called Shopping_Cart. This class contains two simple methods for adding to and subtracting from the shopping cart:

class Shopping_Cart {

    private $cart;

    function __construct($cart="") {
        $this->cart = $cart;
    }

    function getCart() {
        return $this->cart;
    }
   
    function addToCart($item) {
        if(isset($this->cart[$item])) {
            $this->cart[$item]++;
        } else {
            $this->cart[$item] = 1;
        }      
    }

    function deleteFromCart($item) {
        if(isset($this->cart[$item])) {
            $this->cart[$item]--;
            if($this->cart[$item] == 0) {
                unset($this->cart[$item]);
            }
        }
    }
   
}

Using this class, adding products to and subtracting them from the cart is a breeze. Take a moment to work through the following sample behavior:

$cart = new Shopping_Cart();

// Add a copy of "Beginning PHP and MySQL 5, Second Edition"
$cart->addToCart(1);

// Add two copies of "Pro MySQL"
$cart->addToCart(3);
$cart->addToCart(3);

// Output cart
print_r($cart->getCart());

// Delete item from cart
$cart->deleteFromCart(1);

// Output cart again
print_r($cart->getCart());

The resulting output follows:

Array ( [1] => 1 [3] => 2)
Array ( [3] => 2 )

With the shopping cart working as expected, it's time to move on to how we're going to bind the shopping cart to the user as he navigates the website. This is accomplished using PHP sessions.

Binding the Shopping Cart to the User

Chances are your web site's product catalog will be spread across several pages. In order to accommodate the user's desire to manage his shopping cart as he navigates the website, the shopping cart will need to travel with him from one page to the next. Binding such data to a specific user is generally done using a feature known as sessions, which typically involves assigning the user a unique identifier which is stored in a cookie, and then mapping that identifier to his shopping cart contents which reside on the server. Resultingly, with each page request the shopping cart contents can be easily retrieved and displayed to the page, or be manipulated anew before being saved back to the session.

Let's revise the above code to initiate a session, add a few products to the shopping cart, and save the cart to a session. The script concludes with a link to another page, which outputs the session contents to prove the cart did indeed travel with the user's movements:

<?php
   session_start();

   $cart = new Shopping_Cart();

   // Add a copy of "Beginning PHP and MySQL 5, Second Edition"
   $cart->addToCart(1);

   // Add two copies of "Pro MySQL"
   $cart->addToCart(3);
   $cart->addToCart(3);

   // Dump cart contents to array
   $items = $cart->getCart();

   // Assign array to session
   $_SESSION["cart"] = $items;
?>

<a href="nextpage.php">Go to the next page</a>

The nextpage.php script follows:

<?php
  session_start();
  print_r($_SESSION["cart"]);
?>

Executing this script produces the following output:

Array ( [1] => 1 [3] => 2 )

At this point, you understand how both the shopping cart and sessions work together. Next let's build a catalog page and integrate the Ajax.

Adding the Shiny Parts

One of the great side effects of Ajax's booming popularity is the emergence of countless JavaScript frameworks, all intended to reduce the amount of actual programming you have to do with that horrid little language. In an earlier installment I introduced Prototype, so if it's new to you consider reading this tutorial before moving on.

To begin, we'll create the Prototype-driven JavaScript function which will perform the remote call to the server. Below the function, you'll find some simple HTML code which in a real-world situation would be generated by way of a database request. Finally, a link to the shopping cart is provided, although you could just as easily have displayed the cart contents on the same page. For the sake of brevity I'll just show you how to integrate the add feature, and will leave the subtraction mechanism to you as an exercise.

<script src="prototype.js" language="JavaScript" type="text/javascript"></script>
<script type="text/javascript" language="JavaScript">
function manageCart(task,item) {
   var url = 'managecart.php';
   var params = 'task=' + task + '&item=' + item;
   var ajax = new Ajax.Updater(
	          {success: 'cartResult'},
              url,
              {method: 'get', parameters: params, onFailure: reportError});
}

function reportError(request) {
   $F('cartResult') = "An error occurred";
}

</script>

<div id="cartResult"></div>
<p>
Beginning PHP and MySQL 5, Second Edition<br />
<a href="#" onclick="manageCart('add',1)";>Add to Cart</a>
</p>

<p>
Pro MySQL<br />
<a href="#" onclick="manageCart('add',3)";>Add to Cart</a>
</p>

<p>
<a href="viewcart.php">View your shopping cart</a>
</p>

Next, up is the managecart.php. This script is called by the JavaScript function, and is responsible for adding or subtracting an item from the cart. The script is also responsible for returning an appropriate message back to the calling web page:

<?php

include("cart.class.php");
session_start();

$items = $_SESSION["cart"];

$cart = new Shopping_Cart($items);

// Retrieve the parameters
$task = $_GET['task'];
$item = $_GET['item'];

if ($task == "add") {
   $cart->addToCart($item);
   $_SESSION["cart"] = $cart->getCart();
   echo "item added!";
} else {
   $cart->deleteFromCart($item);
   echo "item deleted!";
}
?>

Finally, the simple viewcart.php script. This script is responsible for simply retrieving the shopping cart. You'll need to add a few more lines of code in order to convert the product IDs back to the product names:

<?php
include("cart.class.php");
session_start();
?>
<p>
Your Shopping Cart contains:
<?php
   print_r($_SESSION["cart"]);
?>
</p>

There you have it! An Ajax-enabled shopping cart in very few lines of code, thanks to the power of PHP and the Prototype JavaScript library. I'd love to hear about how you're using what you've learned in this and other installments of this series! Email me at wjATwjgilmore.com.

About the Author

W. Jason Gilmore (http://www.wjgilmore.com/) is the open source editor for Apress. He's the author of the best-selling "Beginning PHP and MySQL 5: Novice to Professional, Second Edition" (Apress, 2006. 913pp.). Along with Robert Treat, Jason is the co-author of "Beginning PHP 5 and PostgreSQL 8: From Novice to Professional". Jason loves receiving e-mail; so don't hesitate to write him at wjATwjgilmore.com.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date