Collection Class Basics

Based on the UML diagram in Figure 5-2, the code skeleton for the Collection class looks like this:

   <?php    class Collection {      private $_members = array();      public function addItem($obj, $key = null) {      }      public function removeItem($key) {      }      public function getItem($key) {      }      public function length() {      }    }    ?> 

The $_members variable provides a location in which to store the objects that are members of the collection. addItem() allows you to add a new object to the collection. removeItem() removes an object. getItem() returns the object, and, of course, we already know that length() returns the number of items in the collection. The Collection class does not require a constructor.

The addItem Method

When adding a new object to the collection, that object is inserted into the $_members array, at the location specified by $key. If no key is provided, you'll allow PHP to pick one. If an attempt is made to add an object to the collection using a key that already exists, an exception should be thrown to prevent inadvertent overwriting of information.

   class Collection {      private $_members = array();      public function addItem($obj, $key = null) {        if($key) {          if(isset($this->_members[$key])) {            throw new KeyInUseException("Key \"$key\" already in use!");          } else {            $this->_members[$key] = $obj;          }        } else {          $this->_members[] = $obj;        }    } 

As with most of the subclasses of Exception used in this book, KeyInUseException has no body, and instead inherits everything from the default Exception class that ships with PHP5.

   class KeyInUseException extends Exception { } 

The KeyInUseException class gives you a means of letting users of the object know when they might be overwriting information by specifying the same key more than once. The value of the key is used as the index in the $_members array. If no key is specified, PHP picks a numeric index for this element. In either case, the object is inserted into the array at that location.

Subclasses of Collection can override the addItem() method with a type hint that will ensure that the items being added are of the correct type for the desired collection. Here's an example:

   <?php    class CourseCollection extends Collection {      public addItem(Course $obj, $key = null) {        parent::addItem($obj, $key);      }    }    ?> 

Using this technique, with very little code you can create subclasses that enforce a data type for the members of the collection.

The getItem and removeItem Methods

The removeItem() and getItem() methods take a key as a parameter to allow you to know which items are being removed or fetched. An exception should be thrown if an invalid key is supplied.

   public function removeItem($key) {      if(isset($this->_members[$key])) {        unset($this->_members[$key]);      } else {         throw new KeyInvalidException("Invalid key \"$key\"!");      }    }    public function getItem($key) {      if(isset($this->_members[$key])) {        return $this->_members[$key];      } else {        throw new KeyInvalidException("Invalid key \"$key\"!");      }    } 

The InvalidKeyException class is just as simple as the KeyInUseException class.

   class KeyInvalidException extends Exception { } 

Other Methods

Because the $key parameter to the addItem() method is optional, you won't necessarily know the key used for each item in the collection. A function called keys() will allow you to provide a listing of those keys to any external code that might need it. The keys will be returned as an array.

   public function keys() {      return array_keys($this->_members);    } 

You might want to know how many items are in the collection. The sizeof PHP function returns the number of elements in an array, so you'll use that to implement your length() method.

   public function length() {      return sizeof($this->_members);    } 

Because getItem() throws an exception if an invalid key is passed, you need to have a means of determining whether a given key exists in the collection. The exists() method will allow you to check before calling getItem().

   public function exists($key) {      return (isset($this->_members[$key]));    } 

This approach allows you to either use a try...catch block to trap for invalid keys or to call the exists() method before calling getItem(), depending on which method is more convenient for a given chunk of code.

Now that you've added all the basic methods to the class, you can move on to see how the Collection class is used.

Using the Collection Class

To use the Collection class as it stands now, create a file called class.Collection.php and save the code for the Collection class into it. Create files for the KeyInvalidException and KeyInUseException classes. Make sure to add require_once statements to the top of class .Collection.php to pull in those exception classes. Save the following code into testCollection.php.

   <?php    /* a silly class for testing */    class Foo {      private $_name;      private $_number;      public function __construct($name, $number) {        $this->_name = $name;        $this->_number = $number;      }      public function __toString() {        return $this->_name.'is number ' . $this->_number;      }    }    $colFoo = new Collection();    $colFoo->addItem(new Foo("Steve", 14), "steve");    $colFoo->addItem(new Foo("Ed", 37), "ed");    $colFoo->addItem(new Foo("Bob", 49));    $objSteve = $colFoo->getItem("steve");    print $objSteve; //prints "Steve is number 14"    $colFoo->removeItem("steve"); //deletes the 'steve' object    try {      $colFoo->getItem("steve"); //throws KeyInvalidException    } catch (KeyInvalidException $kie) {      print "The collection doesn't contain anything called 'steve'";    }    ?> 

Okay, so this example isn't particularly interesting yet, but it should give you some idea of how the Collection class is used. The next section discusses how to handle lazy instantiation, which is one of the primary benefits of this class.

Professional PHP5 (Programmer to Programmer Series)
Professional PHP5 (Programmer to Programmer Series)
Year: 2003
Pages: 182
BUY ON AMAZON © 2008-2017.
If you may any questions please contact us: