Simple Object Iterators in PHP

    Craig Buckler
    Share

    If you’ve been coding in PHP for a while, you may be familiar with the foreach loop. It provides an easy way to analyze every item in an array, e.g.

    
    $myArray = array();
    $myArray[] = "First item";
    $myArray[] = "Second item";
    $myArray[] = "Third item";
    
    foreach ($myArray as $i) {
    	echo "<p>$i</p>";
    }
    

    As well as arrays, it’s also possible loop through an object. If your object contains a collection of items, you can use a foreach loop to iterate over each of them. It doesn’t matter what’s in that collection or how it’s retrieved, e.g.

    • records from a database
    • navigation links
    • names of files within a directory
    • lines of text read from a file
    • product objects in a specific shop category

    Iterators is a subject which strikes fear into the heart of many developers. They sound complex and are often explained with indecipherable abstract references. They’re best explained with a simple example so we’ll create a basic class which defines a list of web technologies:

    
    class WebTechnologies
    {
    	private $tech;
    
    	// constructor
    	public function __construct() {
    		$this->tech = explode( ',', 'PHP,HTML,XHTML,CSS,JavaScript,XML,XSLT,ASP,C#,Ruby,Python') ;
    	}
    
    }
    

    The private $tech array cannot be accessed outside of the class. You could make it public or return its contents, but iterators provide a more elegant alternative.

    Assuming you already have the data in an array, the quickest way to make an object traversable is to implement the IteratorAggregate interface:

    
    class WebTechnologies implements IteratorAggregate
    {...
    

    To complete the code, we must then define a public getIterator() function within our class. This must return something which can be iterated — such an ArrayIterator object with our $tech array passed to its constructor:

    
    // return iterator
    public function getIterator() {
    	return new ArrayIterator( $this->tech );
    }
    

    We can now iterate over all items within the $tech array. The full code:

    
    class WebTechnologies implements IteratorAggregate
    {
    
    	private $tech;
    
    	// constructor
    	public function __construct() {
    		$this->tech = explode( ',', 'PHP,HTML,XHTML,CSS,JavaScript,XML,XSLT,ASP,C#,Ruby,Python' );
    	}
    	
    	// return iterator
    	public function getIterator() {
    		return new ArrayIterator( $this->tech );
        }
    
    }
    
    // create object
    $wt = new WebTechnologies();
    
    // iterate over collection
    foreach ($wt as $n => $t) {
    	echo "<p>Technology $n: $t</p>";
    }
    

    Great. But what if our object’s collection isn’t an array? In that situation, we require more sophisticated iterators … watch out for a full tutorial coming soon.