In this first part of a programming series, you will learn how to create segregated interfaces to perform specific tasks in PHP. In this instance, you will be using them to iterate through arrays.
To start illustrating why segregated interfaces are really useful, in the lines to come I’m going to build an example that will recreate the scenario described in the introduction. Basically, what I want to achieve here is to construct a custom countable array collection.
At this first stage, the collection will only be capable of counting the elements added to it and nothing else; it’ll use only the contract declared by the “Countable” PHP interface. Based on this, here’s how this sample collection looks:
(ArrayCollection.php)
class ArrayCollection implements Countable { protected $_data = array();
/** * Constructor */ public function __construct(array $data = array()) { if (!empty($data)) { $this->_data = $data; } }
/** * Count the number of elements in the collection (implementation required by Countable interface) */ public function count() { return count($this->_data); } }
As you can see, the functionality of the above “ArrayCollection” class is pretty limited. However, this has been done deliberately, as the only thing that the class needs to do, at least for now, is to count its inputted elements.
In keeping with this, the collection only implements the “Countable” native interface, which (not surprisingly) turns out to be a segregated interface, as it only provides its implementer with the functionality that it requires.
Next it’s time to add one more to the earlier array collection. Considering that this class must also be capable of traversing its internal elements, it must then implement the “Iterator” PHP interface.
Making the collection iterable: implementing the “Iterator” interface
The next step that must be taken is to provide the previous array collection with the ability to traverse the elements added to it. Of course, this can be accomplished using another segregated interface, which turns out to the built-in “Iterator”.
Having said that, now check the following code sample, which shows the results of this implementation process:
/** * Constructor */ public function __construct(array $data = array()) { if (!empty($data)) { $this->_data = $data; $this->rewind(); } }
/** * Count the number of elements in the collection (implementation required by Countable interface) */ public function count() { return count($this->_data); }
/** * Reset the collection (implementation required by Iterator interface) */ public function rewind() { reset($this->_data); }
/** * Get the key of the current element in the collection (implementation required by Iterator interface) */ public function key() { return key($this->_data); }
/** * Get the current element in the collection (implementation required by Iterator interface) */ public function current() { return current($this->_data); } /** * Check if there're more elements in the collection (implementation required by Iterator Interface) */
public function valid() { return ($this->current() !== false); }
/** * Move to the next element in the collection (implementation required by Iterator interface) */ public function next() { next($this->_data); } }
Thanks to the use of another segregated interface, the previous array collection class is capable of iterating over its inputted elements by using a “foreach” construct.
Taking into account that this is a straightforward process, which you’ve probably tackled many times before when you wrote your own custom iterators, it’s time to move forward and provide the earlier array collection with the ability for adding, removing and accessing its internal elements. Well, not surprisingly this enhancement procedure can be easily achieved by making the class an implementer of the “ArrayAccess” native interface.