PHP 5 provides a way for objects to be defined so it is possible to iterate
   through a list of items, with, for example a foreach statement. By default,
   all visible properties will be used
   for the iteration.
  
| Example 19-22. Simple Object Iteration | 
<?phpclass MyClass
 {
 public $var1 = 'value 1';
 public $var2 = 'value 2';
 public $var3 = 'value 3';
 
 protected $protected = 'protected var';
 private   $private   = 'private var';
 
 function iterateVisible() {
 echo "MyClass::iterateVisible:\n";
 foreach($this as $key => $value) {
 print "$key => $value\n";
 }
 }
 }
 
 $class = new MyClass();
 
 foreach($class as $key => $value) {
 print "$key => $value\n";
 }
 echo "\n";
 
 
 $class->iterateVisible();
 
 ?>
 | 
 The above example will output: | 
var1 => value 1var2 => value 2
 var3 => value 3
 
 MyClass::iterateVisible:
 var1 => value 1
 var2 => value 2
 var3 => value 3
 protected => protected var
 private => private var
 | 
 | 
  As the output shows, the foreach iterated through all
  visible variables that can be
  accessed. To take it a step further you can implement one
  of PHP 5's internal interface named
  Iterator. This allows the object to decide what and how
  the object will be iterated.
 
| Example 19-23. Object Iteration implementing Iterator | 
<?phpclass MyIterator implements Iterator
 {
 private $var = array();
 
 public function __construct($array)
 {
 if (is_array($array)) {
 $this->var = $array;
 }
 }
 
 public function rewind() {
 echo "rewinding\n";
 reset($this->var);
 }
 
 public function current() {
 $var = current($this->var);
 echo "current: $var\n";
 return $var;
 }
 
 public function key() {
 $var = key($this->var);
 echo "key: $var\n";
 return $var;
 }
 
 public function next() {
 $var = next($this->var);
 echo "next: $var\n";
 return $var;
 }
 
 public function valid() {
 $var = $this->current() !== false;
 echo "valid: {$var}\n";
 return $var;
 }
 }
 
 $values = array(1,2,3);
 $it = new MyIterator($values);
 
 foreach ($it as $a => $b) {
 print "$a: $b\n";
 }
 ?>
 | 
 The above example will output: | 
rewindingcurrent: 1
 valid: 1
 current: 1
 key: 0
 0: 1
 next: 2
 current: 2
 valid: 1
 current: 2
 key: 1
 1: 2
 next: 3
 current: 3
 valid: 1
 current: 3
 key: 2
 2: 3
 next:
 current:
 valid:
 | 
 | 
   You can also define your class so that it doesn't have to define
   all the Iterator functions by simply implementing
   the PHP 5 IteratorAggregate interface.
  
| Example 19-24. Object Iteration implementing IteratorAggregate | 
<?phpclass MyCollection implements IteratorAggregate
 {
 private $items = array();
 private $count = 0;
 
 // Required definition of interface IteratorAggregate
 public function getIterator() {
 return new MyIterator($this->items);
 }
 
 public function add($value) {
 $this->items[$this->count++] = $value;
 }
 }
 
 $coll = new MyCollection();
 $coll->add('value 1');
 $coll->add('value 2');
 $coll->add('value 3');
 
 foreach ($coll as $key => $val) {
 echo "key/value: [$key -> $val]\n\n";
 }
 ?>
 | 
 The above example will output: | 
rewindingcurrent: value 1
 valid: 1
 current: value 1
 key: 0
 key/value: [0 -> value 1]
 
 next: value 2
 current: value 2
 valid: 1
 current: value 2
 key: 1
 key/value: [1 -> value 2]
 
 next: value 3
 current: value 3
 valid: 1
 current: value 3
 key: 2
 key/value: [2 -> value 3]
 
 next:
 current:
 valid:
 | 
 |