今回は、配列を使用したループを組むときに重宝するforeach文のもう一つの機能について紹介します。
このforeachですが、配列だけでなくオブジェクトの反復にも使用することが出来ます。(ただし、PHP5以上のバージョンでしか使えないので注意してください)
これなら、データを取り出すためにwhile文を使用しなくても、foreachを一行書くだけで簡単にイテレーターの処理をすることが出来るので、工数削減や可読性の向上などが可能です。
オブジェクトを引数にした場合、foreach(オブジェクト as メンバ変数名 => メンバ変数の値)となり、アクセス権限のあるメンバ変数を全てを取り出します。
では、早速サンプルを見てみます。
class HogeClass {
public $hoge = "hoge";
public $piyo = "piyo";
public $fuga = "fuga";
protected $foo = "foo";
private $bar = "bar";
function myIterator(){
foreach($this as $key => $val){ //自身のインスタンスをforeachに入れて
echo $key . " => " . $val . "<br>"; //出力
}
}
}
//以下、表示処理
$hoge = new HogeClass();
echo "クラス外からforeach<br><br>";
foreach($hoge as $key => $val){ //インスタンスをforeachに入れて
echo $key . " => " . $val . "<br>"; //出力
}
echo "<br>";
echo "クラス内からforeach<br><br>";
$hoge->myIterator();
出力結果 ----------------
クラス外からforeach
hoge => hoge
piyo => piyo
fuga => fuga
クラス内からforeach
hoge => hoge
piyo => piyo
fuga => fuga
foo => foo
bar => bar
基本的にはメンバ変数を全て表示しますが、クラス外の場合は、protected,privateの変数にはアクセス権がないので表示しません。クラス内では、全ての変数にアクセス出来るので全て表示しています。
また、Iteratorインターフェイスを実装している場合は、その指示にしたがって取り出すことが出来ます。
例えば、以下のように値を最初から3文字だけ切り出す処理を加えると、
class HogeIterator implements Iterator {
private $list = array();
public function __construct($list){
$this->list = $list;
}
public function rewind() {
reset($this->list);
}
public function key() {
return key($this->list);
}
public function current() {
return substr(current($this->list), 0, 3); //ここで3文字切り出す
}
public function next() {
return next($this->list);
}
public function valid() {
return current($this->list) !== false;
}
}
$data = array('hoge',
'piyo',
'fuga');
$i_hoge = new HogeIterator($data);
foreach($i_hoge as $key => $val){
echo $key . " => " . $val . "<br>";
}
実行結果
0 => hog
1 => piy
2 => fug
このように出力を変化させることが出来ます。ですので、例えば、内部ではUNIXタイムスタンプで保持しておき、foreachで取り出すときだけ日本語形式にするなどの処理に使用できます。
このように、オブジェクトを使用する場合にもforeachは役立ちます。もし、機会があれば使用してみてはいかがでしょうか。
この記事は、アシアルが運営するPHP開発者のためのポータル&コミュニティサイト「PHPプロ!」で毎週配信しているPHP・TIPSメーリングリストを再録したものです。
同サイトでは、他にもPHP最新ニュースや、困ったときのQ&A掲示板、初心者向けのPHP講座など、PHP開発者をサポートする情報を掲載しています。