Object Iteration

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.

例子 19-20. Simple Object Iteration

<?php
class 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 ();

?>

上例将输出:

var1 => value 1
var2 => 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.

例子 19-21. Object Iteration implementing Iterator

<?php
class 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 " ;
}
?>

上例将输出:

rewinding
current: 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.

例子 19-22. Object Iteration implementing IteratorAggregate

<?php
class 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 " ;
}
?>

上例将输出:

rewinding
current: 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:

注: For more examples of iterators, see the SPL Extension .