オブジェクトの反復処理の使いどころ
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() とか、かな。カプセル化を壊してしまうので、使うとしたらオブジェクトの内部?
今のところ、コレを使えば楽になってたな〜という所は思いつかない。うーむ。