[ Team LiB ] Previous Section Next Section

Constraining Arguments to Methods with Hints

In PHP 4, and most of the time in PHP 5, you have to rely on type-checking code and naming conventions to signal the argument types your methods expect. This generally suffices but can lead to error-prone code when the wrong data type is passed to the wrong argument variable.

Let's create a method that collects Item objects to illustrate some of the dangers that a relaxed attitude toward type can bring:


class ItemLister {
  private $items = array();

  function addItem( $item ) {
    array_push( $this->items, $item );
  }

  function splurgeItems () {
    foreach( $this->items as $item ) {
      print $item->getProductString ();
      print "<br />";
    }
  }
 }

The ItemLister class is very simple indeed. It uses the addItem() method to collect Item objects. The splurgeItems() method simply loops through all stored Item objects, calling the getProductString() method on each of them. Here's how we might work with the ItemLister class:


$lister = new ItemLister();
$lister->addItem( new Item ("widget", 5442) );
$lister->addItem( new Item ("spogget", 676) );
$lister->addItem( new Item ("kapotchnak", 88) );
$lister->addItem( new Item ("floobit", 21) );
$lister->splurgeItems ();

As long as you are in charge of working with ItemLister, all should be well. What happens, though, if a coder joins your project without a good understanding of Item and ItemLister objects and passes an ItemLister the wrong kind of object?


class WrongClass { }
$lister = new ItemLister();
$lister->addItem( new WrongClass() );
$lister->splurgeItems ();

This code generates an error, but only when the splurgeItems() method of the ItemLister object attempts to invoke WrongClass::getProductString():



Fatal error: Call to undefined method wrongclass::getProductString() in /home/mz/htdocs
graphics/ccc.gif/wrongargs.php on line 11

In other words, the ItemLister class has stored the wrong kind of object in its $items property, and we only find out about it some time later. This kind of separation between the cause of an error and its effect can be hard to debug. Ideally, we want to catch the error when addItem() is called and not at some indeterminate future point.

We can do so in PHP 4 by adding type-checking code to addItem(). This is a timeconsuming chore, however, and in practice usually omitted. We will cover techniques for testing object types in the section "Testing Classes and Objects."

PHP 5 gives us a neat way of constraining the type of object arguments. We can use hints. A hint is simply the name of an object type placed before the argument variable in a method declaration:


function addItem( Item $item ) {
 array_push( $this->items, $item );
}

If anything other than an Item object is passed to addItem() in this fragment, a fatal error is generated:


Fatal error: Argument 1 must be an instance of Item

Unfortunately, this kind of checking only works with objects. You still must manually test primitive types such as integers and floats.

    [ Team LiB ] Previous Section Next Section