This article covers making a custom iterator type container in PHP. When I talk about a “container” I mean a class that holds something, often in a similar was that an array does. Adding iterator capabilities to it means it will work with a foreach statement like an array does too, and once you complete it you will then be able to add custom functionality to the class that goes beyond what an array can do. (You will need PHP 5+ to use this code.)

I’ll just show you the whole class, and you can take a look and try to grasp what is going on.

class container implements Iterator{

    private $var = array();

    public function __construct()
    {
    }
    public function set($value, $key=-1)
    {
        if($key == -1){
            $this->var[] = $value;
        }else{
            $this->var[$key] = $value;
        }
    }
    public function delete($key)
    {
            unset($this->var[$key]);
    }
    public function get($key)
    {
        return $this->var[$key];
    }
    public function count()
    {
        return count($this->var);
    }
    public function rewind()
    {
        reset($this->var);
    }
    public function current()
    {
        $var = current($this->var);
        return $var;
    }

    public function key()
    {
        $var = key($this->var);
        return $var;
    }

    public function next()
    {
        $var = next($this->var);
        return $var;
    }

    public function valid()
    {
        $key = key($this->var);
        $var = ($key !== NULL && $key !== FALSE);
        return $var;
    }

}

The class is just based on the standard example from the PHP manual. It is different however, it allows you to set and get (and unset) variables in the array that is inside the class. In a way this is a wrapper for an array, rather than inheriting from an array or fully duplicating an array’s capabilities. The class does inherit from the Iterator class.

The functions rewind(), current(), key(), next(), and valid() are what make the iterator capability work. We don’t really have to have them defined this way if we inherit from the right class, but I wanted to show them defined because it would allow you to create custom behaviors there in the future. That’s the point of this class. As it is it is just an inferior version of an array, but once you start customizing it the possibilities are endless.

Next we just test it and get familiar with using it.

$mycontainer = new container();
$mycontainer->set("Cats", 9);
$mycontainer->set("DOGS", 90);
$mycontainer->set("Rats", 900);
foreach($mycontainer as $key => $value){
    echo "$key :: $value n";
}

Exactly as you probably thought it would work, 3 halues are set and 3 are printed. The second parameter of set() is the key, which can be omitted. The next example does not use the iterator part of the class but note that it basically doesn’t work if you use the second parameter of set. It is only functional in the following manner.

$mycontainer = new container();
$mycontainer->set("Cats"); //with second parameter omitted this is key 0
$mycontainer->set("DOGS");//1
$mycontainer->set("Rats");//2
for($i = 0; $i < $mycontainer->count(); $i++){
        echo "$i :: " .  $mycontainer->get($i) . " n";
}

That should have printed the same values as before but with the keys 0, 1, 2. Now you can see why the iterator is usefull for anything that does not use completely continuous numeric keys. Even using $mycontainer->delete(1); would throw off the for() loop.

Now that you have a class and know how to use it, try to think of ways to make it useful. There are many possible features that a container class could have:
Sorting
Searching
Hashing
Type Checking
Error Checking
Checking for duplicates
Limited Sizes
Variable iterator start and stop indexes
Variable type returns like choosing to iterate as float or int
Efficiency in speed or by using less memory