PHP5にはIteratorインターフェイスというものが存在しますが、このインターフェイスを実装すると、それがそのオブジェクトのforeachの挙動になります。
http://php.benscom.com/manual/ja/class.iterator.php
適当なクラスを作成し、それに対して
foreach($MyClass as $key=>$val)
とやったときの$keyと$val、そしてその出現内容や順番なんかを自由に変更できるのです。
特に意味はありませんが、適当に文字列を突っ込んだら50音順に取り出せるクラスを作ってみます。
example_foreach.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
class Example_Foreach implements Iterator{
//変数
protected $words=array(); //配列入れ
protected $current=0; //現在値
//コンストラクタ
public function __construct(){}
//追加
public function set($word){
$this->words[]=$word;
sort($this->words,SORT_STRING);
}
//検索対象の全件数を返す
public function count(){
return count($this->words);
}
//イテレータ(foreachの実装)
public function current(){
return $this->words[$this->current];
}
public function key(){
return $this->current;
}
public function next(){
$this->current=$this->current+1;
}
public function valid(){
if(isset($this->words[$this->current])){
return true;
}
return false;
}
public function rewind(){
$this->current=0;
}
#↓クラスのおわり
}
|
使用時は普通にset()してforeachで取り出すだけです。
example.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
require_once('example_foreach.php');
$obj=new Example_Foreach();
$obj->set('a');
$obj->set('d');
$obj->set('e');
$obj->set('c');
$obj->set('b');
foreach($obj as $key=>$val){
$ret[$key]=$val;
}
|
$retはarray('a','b','c','d','e')という配列になります。
Example_Foreachには他にも$currentという変数や幾つかのメソッドがあるのに、それは無視されて、$wordsの中身だけが返ってきます。
Iteratorインターフェイスに存在するcurrent()、key()、next()、valid()、rewind()の各メソッドを実装することで、foreachの挙動を変更することができました。
ここでは単純に小さい順に取り出しましたが、メソッドを変更することで順番を変更したり、返り値を文字列以外のものにしたりといったことが自由に行えます。
ただ注意事項として、うっかり変な実装をすると、特にnextあたりを間違えると容易に無限ループになってしまうので気をつけましょう。
next(){}とかやってしまうとブラウザが死にます。
まあ、この程度ならいちいちオブジェクトにせず、配列に入れてsortした方が早い(というかIteratorが遅い)というのは秘密だ。
PR
トラックバック
トラックバックURL: