PHP5开始支持了接口, 并且内置了Iterator接口, 所以如果你定义了一个类,并实现了Iterator接口,那么你的这个类对象就是ZEND_ITER_OBJECT,否则就是ZEND_ITER_PLAIN_OBJECT.
对于ZEND_ITER_PLAIN_OBJECT的类,foreach会通过HASH_OF获取该对象的默认属性数组,然后对该数组进行foreach.
而对于ZEND_ITER_OBJECT的类对象,则会通过调用对象实现的Iterator接口相关函数来进行foreach。
/*** @author 简明现代魔法 http://www.nowamagic.net*/class MyIterator implements Iterator{ private $var = array(); public function __construct($array) { if (is_array($array)) { $this->var = $array; } } public function rewind() { echo "倒回第一个元素\n"; reset($this->var); } public function current() { $var = current($this->var); echo "当前元素: $var\n"; return $var; } public function key() { $var = key($this->var); echo "当前元素的键: $var\n"; return $var; } public function next() { $var = next($this->var); echo "移向下一个元素: $var\n"; return $var; } public function valid() { $var = $this->current() !== false; echo "检查有效性: {$var}\n"; return $var; }}$values = array(1,2,3);$it = new MyIterator($values);foreach ($it as $k => $v) { print "此时键值对 -- key $k: value $v\n\n";}
一般的迭代器内部需要下面的方法:
- Iterator::current — Return the current element 返回当前元素
- Iterator::key — Return the key of the current element 返回当前元素的键
- Iterator::next — Move forward to next element 移向下一个元素
- Iterator::rewind — Rewind the Iterator to the first element 重新回到第一个元素
- Iterator::valid — Checks if current position is valid 检查当前位置的有效性
运行一下上述代码的结果,可以看一下迭代器的运行原理:
倒回第一个元素当前元素: 1检查有效性: 1当前元素: 1当前元素的键: 0此时键值对 -- key 0: value 1移向下一个元素: 2当前元素: 2检查有效性: 1当前元素: 2当前元素的键: 1此时键值对 -- key 1: value 2移向下一个元素: 3当前元素: 3检查有效性: 1当前元素: 3当前元素的键: 2此时键值对 -- key 2: value 3移向下一个元素: 当前元素: 检查有效性:
当然,你也可以换种方法实现迭代器里面五个固定功能方法:
_items = $data; } public function current(){ return $this -> _items[$this ->_current]; } public function next(){ $this ->_current ++; } public function key(){ return $this ->_current; } public function rewind(){ $this ->_current = 0; } public function valid(){ return isset($this -> _items[$this -> _current]); }}$arr = array(1, 2, 3);$arr2 = new Sample($arr);foreach($arr2 as $key => $value){ echo $key . '==' . $value . '';}
用法(实现一个):
/*** @author 简明现代魔法 http://www.nowamagic.net*/class Fibonacci implements Iterator { private $previous = 1; private $current = 0; private $key = 0; public function current() { return $this->current; } public function key() { return $this->key; } public function next() { // 关键在这里 // 将当前值保存到 $newprevious $newprevious = $this->current; // 将上一个值与当前值的和赋给当前值 $this->current += $this->previous; // 前一个当前值赋给上一个值 $this->previous = $newprevious; $this->key++; } public function rewind() { $this->previous = 1; $this->current = 0; $this->key = 0; } public function valid() { return true; } } $seq = new Fibonacci; $i = 0; foreach ($seq as $f) { echo "$f "; if ($i++ === 15) break; }
php SPL(Standard PHP Library)标准库封装的一些的迭代器,遍历文件夹,遍历文件等等。
http://blog.csdn.net/uuleaf/article/details/7635996
http://php.net/manual/en/spl.iterators.php