オブジェクトの反復処理の使いどころ

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

PHP: オブジェクトの反復処理 - Manual

使ったことがないので、試してみる。
まず、次のようなクラス A を作ってみる。

<?php
class A
{
  public    $pub = 'public';
  protected $pro = 'protected';
  private   $pri = 'private';

  public    static $s_pub = 'public static';
  protected static $s_pro = 'protected static';
  private   static $s_pri = 'private staitc';

  public function iterate()
  {
    foreach ($this as $name => $value) {
      echo "{$name}:{$value}", PHP_EOL;
    }
  }
}

iterate メソッドを呼ぶとすべてのインスタンス変数が表示される。

<?php
$a = new A();
$a->iterate();

# pub:public
# pro:protected
# pri:private

A のインスタンスを foreach を使ってイテレートすると、public 変数だけが出力される。

<?php
$a = new A();
foreach ($a as $name => $value) {
  echo "{$name}:{$value}", PHP_EOL;
}

# pub:public 

A のサブクラスで itarate を A と同様の内容でオーバライドすると、 private 変数以外が表示される。

<?php
class B extends A
{
  public function iterate()
  {
    foreach ($this as $name => $value) {
      echo "{$name}:{$value}", PHP_EOL;
    }
  }
}

$b = new B();
$b->iterate();

# pub:public
# pro:protected

参照を使えば内容を書き換えられる。

<?php
$a = new A();
foreach ($a as &$prop) {
  $prop = 'aiueo';
}
var_dump($a);

# object(A)#1 (3) {
#   ["pub"]=>
#   &string(5) "aiueo"
#   ["pro":protected]=>
#   string(9) "protected"
#   ["pri":"A":private]=>
#   string(7) "private"
# }

まあ、想像通りかな。static 変数は対象にならないようだ。

次に、__get() メソッドでプロパティにアクセスするクラスの場合を考えてみる。

<?php

class C
{
  private $props = array('foo' => 'var');
  public  $pub   = 'pub';

  public function __get($name)
  {
    return $this->props[$name];
  }
}

$c = new C();
foreach ($c as $name => $value) {
  echo "{$name}:{$value}", PHP_EOL;
}

# pub:public

public 変数のみが表示された。マジックメソッドを通じてというのはダメらしい。

しかし、この機能はどこで力を発揮するのだろうか。パッと思いつくのは __toString() とか、かな。カプセル化を壊してしまうので、使うとしたらオブジェクトの内部?
今のところ、コレを使えば楽になってたな〜という所は思いつかない。うーむ。