Using the Countable Interface

PHP provides a number of predefined interfaces and classes that can really make your life as a developer easier but which are often overlooked. The functionality offered by the Standard PHP Library (SPL) and the predefined interfaces is extremely cool and very powerful but very underutilised. I’ve found myself reaching more and more for these features recently and it set me to thinking why are they not more widely used? After a little bit of thought I think I’ve worked it out. For the most part PHP extensions allow you to achieve some concrete action which is easy to grasp. In comparison it’s much harder to see what the SPL and predefined interfaces are going to do for you. While they let you hook into the core PHP engine in really powerful and useful ways it’s not easy to see at first glance how to use them. The problem is in a lack of ‘real-world’ examples. While most of this functionality is well documented the examples are often somewhat dry and academic. This isn’t really the fault of the PHP manual: the functionality in the SPL or predefined interfaces can be applied to so many different ways that it’s hard to provide concrete uses for them. I thought I’d write a few articles with examples of how I’ve used these classes and interfaces in the hope that someone would find it useful. I’d love it if people felt like commenting with their own examples too. I’ll start with a quick look at the Countable interface.

The Countable Interface

The Countable interface at it’s simplest level allows you to pass objects that implement it to PHP’s native count function. The interface is, on the surface, extremely easy to implement. You only need to add the Countable::count() method to implement the interface in your class and this method only needs to return an integer. If you pass an object that implements Countable to the PHP count function the PHP interpreter will automatically call the count method in the object, returning the value from it to you to use.

Why is Countable so Useful?

Like all of the predefined interfaces and SPL functionality the real power of countable comes from the ability to effectively override and re-implement core PHP functionality with your own logic. I’ll give three brief examples here of ways that I’ve personally used Countable recently.

Accessing the State of a Private or Protected Property

One of the simplest uses of countable is to return the count of an array that’s held as a protected or private property of an object. Take the following example:


class SomeClass implements Countable {

 protected $_data = array();

 public function doSomething()
 {
//Code to change $_data here
 }

 public function count()
 {
return count($this->_data);
 }
}

In this example some data is stored in the object as an array and the Countable:Count method simply returns the count of that array. While this is obviously a very simple example it can be very powerful. I’ve been doing a lot of work with a web service in the last few weeks and have used code very much like this. After a web service call the resulting XML is processed using XPath and the resulting array is stored in a protected property. The count method would then return the number of results of the web services call. Using count in this way obviously makes a lot of sense when coupled with implementing Iterator or ArrayAccess to allow access to the data held in the protected property.

Using Countable to Signal the State of an Object

Countable can also be used to signal the state of an object. Imagine the above code, amended slightly to this:


class SomeOtherClass implements Countable {

protected $_data;

public function doSomething()
{
//Code to change $_data here
}

public function count()
{
return is_null($this->_data) ? 0 : 1;
}
}

In this case count will only ever return 0 or 1, depending on whether the protected property $_data has a value set in it or not. Using this code could look something like this:


$obj = new SomeOtherClass();

$obj->doSomething();

if (count($obj)) {

//$_data is not null, proceed accordingly.

}

I’ve also used this recently with a web service call. In this case the web service call was expected to return a single value, which is stored in $_data. Implementing countable like this simply signifies to the calling code if a value has been successfully retrieved or not.

Using Countable with a Database Table

Another interesting use of Countable is with a class that maps to a database table in some way. Imagine a case where you have a database table where values are only considered ‘live’ if some condition is met. Implementing countable on an object that encapsulates the db table can then be used to flag if the table contains any ‘live’ values. The following example uses Zend_Db_Table:


class AnotherClass extends Zend_Db_Table implements Countable {

 public function count()
 {
$select = $this->select(Zend_Db_Table::SELECT_WITH_FROM_PART)
->from('some_table', array('Count' => 'COUNT(*)'))
->where('SomeCondition = SomeValue');
$row = $this->fetchRow($select);
return (int) $row->Count;
 }
}

In your calling code you would then simply do this:


$obj = new AnotherClass();

if (count($obj)) {

//Table has 'live' values. Do something here

}

This can be a very useful way of working with a database table.

A Word of Caution…

The only limit to the way Countable can be used is the imagination of the developer, and this is also a danger. All developers are familiar with using the count() function to get hold of the number of values in an array. When implementing Countable the further you move the count() method away from this functionality the less intuitive the code becomes and the greater the chance that the developer using it might make a mistake. This is true of all of the predefined interfaces however. While they provide great power the further away from core PHP functionality you get while implementing them in your own code the less intuitive they become. However, don’t let this stop you! The next time you go to write a method called something like ‘getItemCount()’ in a class don’t do it! Implement the Countable interface instead and start hooking into the power of the core PHP engine.

6 thoughts on “Using the Countable Interface

  1. Thank you for your post, it’s really a good idea to provide some example for interfaces in SPL. However, I don’t really get the point here. Why would be writing this code:


    if (count($obj)) {
    //$_data is not null, proceed accordingly.
    }

    better then writing:


    if ($obj->count()) {
    //$_data is not null, proceed accordingly.
    }

    ?

    1. Hi Julien,

      Thanks for the comment. I don’t think that either example you post is better than the other: both are totally valid and how you use the count() method is entirely down to the developers taste. I personally prefer calling the count() method through the count function though. One of the primary purposes of the predefined interfaces is to allow you to hook into and to override core PHP behaviour so to me implementing Countable and then not using it through the count function just feels wrong. However, that really is just my subjective opinion for what it’s worth!

  2. Hi,

    Thanks for this post, I think I’ll be using the Countable interface sometime.

    You say

    Countable can also be used to signal the state of an object.

    and

    the further you move the count() method away from this functionality the less intuitive the code becomes

    I’d argue that you didn’t heed your own warning :-). The example with the Countable records that were live was better imho.

    Thanks again for the post!

Leave a Reply