オブジェクトのイタレーション

PHP 5は、アイテムのリストに関して反復処理、例えば、 foreach 命令、 を可能とするように、オブジェクトを定義する手段を提供します。 デフォルトで、 全ての アクセス権限がある プロパティは、反復処理に使用することができます。

例 19-22. 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

出力からわかるように、 foreach による 反復処理が全ての アクセス権がある 変数について行われています。 さらに、 Iterator という名前のPHP 5の内部 interface implement することもできます。 これにより、オブジェクトは、どうやって、反復されるかを決めることが できます。

例 19-23. 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:

単にPHP 5の IteratorAggregate インターフェイスを 実装することにより、 Iterator 関数を 全く定義する必要なく、自分のクラスを定義することも可能です。

例 19-24. 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:

注意: より詳細なイタレータの例については、 SPLエクステンション を 参照してください。