SPL Iterator

Introduction

The SPL Iterator allows for an object to be used in foreach loops.

foreach($object as $current)
{
    // Do Stuff.
}

Iterator Interface

interface Iterator
{
    function key();

    function current();

    function next();

    function valid();

    function rewind();
}

The execution path of the Iterator is as follows:

  1. Rewind() : Only called at the start of the Iteration and won’t be called until it is used in another foreach loop.
  2. Next()
  3. Valid()
  4. Current()
  5. Key() : Called Last because it is ”Optional”.

Rewind

For every foreach loop that you use the Iterator Object, rewind will be called to reset the elements. This method is called before the iteration starts. For example, it is like this.

$iterator->rewind();

while($iterator->valid())
{
    $key = $iterator->key();
    $current = $iterator->current();

    $iterator->next();
}

Except, you only have to give the variables for the key and current. Saves a lot of work in the long run.

Next

You don’t have to check whether there is another element after the current one, do the checking in the valid method. Just move to the next element.

Valid

Return true if there is a ”’current”’ element available or false when the end has been reached.

Current

Most used method and you can return any information that the user needs here. Don’t return multiple elements for the user.

Key

The key entry is optional in the foreach loop, so if you are going to use it to return data, you should specify in the manual. Most likely candidates for key are if you have multiple levels of iteration

foreach($iterator as $key => $currentObj)
{
    echo $key;
    foreach($currentObj as $key => $current)
    {

    }
}

Others are for returning the number of iterations that were preformed or what number the row is at. I used it to return the table name for one project. Carefully consideration should be taken for what is returned in the key method. Return nothing and only use current if you are unsure.

Examples

”’There is no guarantee that the code is functional.”’

Array Iterator

class MyArrayIterator implements Iterator
{
    protected $dataStore = null;

    // Array hinting was added in 5.1.x,
    // in PHP 5.0.x, is_array($data) should be used
    public function __construct(array $data)
    {
        if(is_array($data)) { // For PHP 5.0.x
            $this->dataStore = $data;
        }
    }

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

    public function current()
    {
        return current($this->dataStore);
    }

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

    public function rewind()
    {
        return reset($this->dataStore);
    }

    public function valid()
    {
        // When Next passes over the end of the array,
        // current() should return false. Needs to be tested.
        return (bool) $this->current();
    }
}

Mysql Iterator

class MysqlIterator implements Iterator
{
    protected $row = null;
    protected $query = null;

    public function __construct($query)
    {
        if(is_string($query)) {
            $this->query = mysql_query($query);
        } else if(is_resource($query)) {
            $this->query = $query;
        }
    }

    public function key() { } // Not Implemented

    public function current()
    {
        if($this->row != null)
        {
            return $this->row;
        }
    }

    public function next()
    {
        $this->row = mysql_fetch_assoc($this->query);
        return $this->row;
    }

    public function rewind()
    {
        $this->row = mysql_data_seek($this->query, 0);
        return $this->row;
    }

    public function valid()
    {
        if($this->row == false) {
            return false;
        }

        return true;
    }
}

Possibly Related Posts:


Tags: , ,

One Response to “SPL Iterator”

  1. sobstel says:

    Note for MyArrayIterator::valid() – what if array current value is actually FALSE? You should also make strict check ($this->current() !== false)