jump to navigation

Exploring SPL : An Introduction to Iterators January 21, 2013

Posted by Tournas Dimitrios in PHP.
trackback

The Standard PHP Library (SPL) is a set of functions , Classes and Interfaces built into PHP since version 5.0 , and as of PHP 5.3 it cannot even be disabled . Each new PHP-release , expands this library with new features (by adding new Classes and Interfaces) . SPL has a broad range of build-in functionality , ranging from auto-loading and Exception-handling ,  up to event driven code (Observer design pattern) . One part of SPL’s functionality is devoted to iterations , which is achieved by implementing the Iterator design pattern . The term “Iterator” is used in different aspects of the software development process , conceptually : it describes a general reusable solution to achieve the iteration functionality  . From the implementation “point of view” , an Iterator is an object that traverses a data-structure (eg: an array , a directory listing or possibly a set of database result sets or other resource)  . Lastly , PHP uses the term “Iterator”  to label all these Classes (or Interfaces) that have build-in iteration functionality (which is guaranteed by extending the Iterator Interface , or one of its derivatives) .

Iteration in simple words : it’s basically all about loops (one of the most common building-blocks of all programming languages) . SPL  provides a plethora of specialized tools (Interfaces , Classes) that affect the behavior of the loop . Just to mention a few : FilterIterator , CachingIterator , LimitIterator , RegexIterator  (hope the name is self-explanatory ) . Future articles will present practical examples of all these filters .

The iterator is best understood if we have a firm knowledge of how arrays are iterated in PHP . First, let’s refresh ourselves with an actual foreach loop construct .

$elements = array(
    "firstelement",
    "secondelement",
    "lastelement",
);
foreach($elements as $k => $v) {
  echo $k , '   ' , $v , '<br>' ;
}

All actions that the “foreach-loop” performs internally are available as functions , so we could actually write our own foreach using the following code .

<?php
/**
 * Created by Tournasdimitrios.
 * Date: 1/20/13
 * Time: 4:51 PM
 */

class myIterator {
    private $_position = 0;
    private $_elements = array() ;
    public function __construct($elements) {
    $this->_position = 0;
    $this->_elements = $elements ;
    echo '<b>constructor instantiated</b><br>' ;
    }

    function rewind() {
    echo __METHOD__;
    $this->_position = 0;
    echo '<br>' ;
    }

    function current() {
    echo __METHOD__;
    return '----> Data is :'. $this->_elements[$this->_position];

    }

    function key() {
    echo '<br>' ;
    echo __METHOD__ ;
    return $this->_position;

    }

    function next() {
    echo __METHOD__;
    ++$this->_position;
    echo '<br>' ;
    }

    function valid() {
    echo __METHOD__;
    return isset($this->_elements[$this->_position]);

    }
}
 $elements = array(
        "firstelement",
        "secondelement",
        "lastelement",
    );

$it = new myIterator($elements) ;
echo '========== Using For-Loop  ===========<br>' ;
for ( $it->rewind(); $it->valid(); $it->next() ) {
  echo '--------Strarting the loop-------' ;
  echo  $it->current()   ;
  $key = $it->key() ;
  echo '<br>' ;
  echo '-------Stopping the loop---------' ;

}

The loop is implemented in five steps :

  1. Initialize the loop by resetting the key-pointer
    ($it->rewind()
  2. Is the condition valid , ie can we have another loop ?
    ($it->valid() )
  3. If valid (see previous step) , get content of current key-position
    ($it->current() )
  4. Increase the current position
    ($it->key() )
  5. Goto next key-position and repeat the loop , ie step 2
    ($it->next() )

The outcome of previous code is illustrated in the following screenshot :

Exploring SPL

One may ask , why should we write all this code by hand while the foreach loop does everything behind the scenes for us ? Well … , Iterators are included in PHP because it lets you use common language constructs (such as foreach) with arbitrary objects , instead of being restricted to loop over built-in objects like arrays . Of course , one could start from the ground up and build a custom  Iterator by extending one of PHP’s build-in Iterator Interfaces ( Iterator , ArrayAccess  and Traversable ) . Besides the fact that these Interfaces guarantee that the derived Classes will actually implement the aforementioned 5-step loop process  , these Interfaces also take care to trigger each step automatically (instead of the manually process ) . The following code demonstrates how this works , notice this time , the foreach loop triggers all steps automatically :

<?php
/**
 * Created by Tournas Dimitrios
 * Date: 1/20/13
 * Time: 5:16 PM
 */
// Iterator
class myIterator implements Iterator {
    private $_position = 0;
    private $_elements = array() ;

    function __construct($elements) {
    $this->_elements = $elements  ;
    $this->_position = 0;
    echo 'constructor initiated <br>' ;
    }

    function rewind() {
    echo __METHOD__;
    $this->_position = 0;
    echo '<br>' ;
    }

    function current() {
    echo __METHOD__;
    return $this->_elements[$this->_position];

    }

    function key() {
    echo '<br>' ;
    echo __METHOD__ ;
    return $this->_position;
    }

    function next() {
    echo __METHOD__;
    ++$this->_position;
    echo '<br>' ;
    }

    function valid() {
    echo __METHOD__;
    echo '<br>' ;
    return isset($this->_elements[$this->_position]);

    }
}
$elements = array(
    "firstelement",
    "secondelement",
    "lastelement",
);

$it = new myIterator($elements) ;
echo '========== Using Foreach-Loop  ===========
' ;
foreach($it as $key => $value) {
    echo '------>  ' , $key , '  :  ' , $value . '<br>'  ;
    echo '<br>----- STARTING NEXT LOOP -------<br>' ;
}
echo '========== Using For-Loop  ===========<br>' ;
for ( $it->rewind(); $it->valid(); $it->next() ) {
    $curent = $it->current() ;
    $key = $it->key() ;

}

For  common Iteration tasks , SPL has pre-build Classes which have the whole process encapsulated , so we don’t have to worry about the 5-step implementation (writing functions like : next , reset , valid ,current and key ) . Sometimes you may find these Classes too general and they may not always do what you need . In such cases you can easily extend these classes and add your own functionality (or tweak existing as needed) .
The real power of Iterators begin to shine when we have to handle  large data-sets , while the foreach structure has to copy the whole object into memory  (even for a bit of change) , the Iterator is handling everything on the fly . This economy in system resources (memory) is noticeable on large data-sets . SPL Iterators  expose visibility to one element at a time making them far more efficient .
Future articles will present practical examples , everyone that has well understood these basic concepts , shouldn’t have any difficulty to follow . Keep tuned 🙂

Advertisements

Comments»

1. Exploring SPL : An Overview of the Iterator and IteratorAgreggate Interface « Tournas Dimitrios - January 23, 2013

[…] previous article (introduction to Iterators) made a short introduction about Iterators and the basic concepts of their functionality . This […]

2. lesli - January 23, 2013

This page certainly has all of the information I needed concerning this subject and didn’t know who to ask.

3. Juegos - January 25, 2013

Just wish to say your article is as astonishing.
The clarity in your post is simply great and i could assume you’re an expert on this subject. Fine with your permission allow me to grab your feed to keep up to date with forthcoming post. Thanks a million and please continue the enjoyable work.

4. Clm - February 6, 2013

interesting stuff, i might search for more information about this, thanks a lot friend.

5. Earl Kleinhenz - February 6, 2013

I just want to mention I’m very new to blogging and honestly enjoyed this web-site. Almost certainly I’m planning to bookmark your website . You certainly come with remarkable writings. Bless you for sharing your website page.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s