- The Cart Class?s Needs
- Defining the Cart Class
- Making the Cart Iterable and Countable
- The Item Class
- Using the Code
- Conclusion
Defining the Cart Class
To start, the cart class needs an internal array for storing all the items in the cart:
class ShoppingCart { protected $items = array();
I’ve made this attribute protected, not private, just in case you need to derive another shopping cart class from this one.
Next, the isEmpty() method of the class can be used to quickly see whether or not there are items in the cart. It returns a Boolean:
public function isEmpty() { return (empty($this->items)); }
The addItem() method should add items to the cart. Here it is in full, then I’ll explain it:
public function addItem(Item $item) { // Need the item id: $id = $item->getId(); // Throw an exception if there's no id: if (!$id) throw new Exception('The cart requires items with unique ID values.'); // Add or update: if (isset($this->items[$id])) { $this->updateItem($item, $this->items[$item]['qty'] + 1); } else { $this->items[$id] = array('item' => $item, 'qty' => 1); } } // End of addItem() method.
The method takes one argument of type Item. This restriction is accomplished via PHP’s type hinting ability, and an exception will be thrown if an Item object is not received (see Figure 1).
Figure 1 The exception thrown if the correct type of value is not received by a method.
I’ll explain the Item class later in the article, but understand now that so long as the items used by your site are of type Item, or a derived class, this will work.
Items are stored in the internal array using the item ID as the index. The item ID should be a unique reference to each item the site sells, whether that means an automatically incremented primary key or a string SKU. This method must therefore first find the item ID by calling the Item object’s getId() method.
If no ID value exists, an exception is thrown. (I’ve included an example of this validation here, but have omitted it from the other methods in the class for the sake of brevity.)
Next, the method has a check to confirm that this is a new item being added to the class, rather than another of an existing item being added. That check just sees if there’s already an element in the array indexed at the ID. If so, then the updateItem() method will be called instead, passing along the item being added/updated and a quantity of one more than the current quantity (this will mean more when you see the full class definition).
If this is indeed a new item to the cart, then the item is added as an array to the items array, indexed at the item’s ID value.
Next, let’s write the updateItem() method. It could be called internally (as just shown), or when a form is submitted to update the quantities of the items in the cart.
public function updateItem(Item $item, $qty) { // Need the unique item id: $id = $item->getId(); // Delete or update accordingly: if ($qty === 0) { $this->deleteItem($item); } elseif ( ($qty > 0) && ($qty != $this->items[$id]['qty'])) { $this->items[$id]['qty'] = $qty; } } // End of updateItem() method.
As you can see, the method is similar to addItem(), except that it takes both an item and a quantity as its arguments. If the quantity is 0, then the item is removed from the cart. Otherwise, so long as the quantity is a positive integer and not equal to the current quantity, that item’s quantity is updated in the cart.
The deleteItem() method just removes the item from the cart:
public function deleteItem(Item $item) { $id = $item->getId(); if (isset($this->items[$id])) { unset($this->items[$id]); } }
And that concludes the core functionality. Let’s make it more useful, though, by applying two interfaces defined in the Standard PHP Library.