PHP的迭代器

最孤独的,不是不能跟一个人在一起,而是根本不知道想跟谁在一起......

说明

PHP5开始支持了接口, 并且内置了Iterator接口, 所以如果你定义了一个类,并实现了Iterator接口,
那么你的这个类对象就是ZEND_ITER_OBJECT,否则就是ZEND_ITER_PLAIN_OBJECT.
对于ZEND_ITER_PLAIN_OBJECT的类,foreach会通过HASH_OF获取该对象的默认属性数组,然后对该数组进行foreach.
而对于END_ITER_OBJECT的类对象,则会通过调用对象实现的Iterator接口相关函数来进行foreach。

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
<?php

/**
* Iterator模式的简单实现类
*/
class sample implements Iterator {
private $_items ;

public function __construct(&$data) {
$this->_items = $data;
}
public function current() {
return current($this->_items);
}

public function next() {
next($this->_items);
}

public function key() {
return key($this->_items);
}

public function rewind() {
reset($this->_items);
}

public function valid() {
return ($this->current() !== FALSE);
}
}

/** DEMO */
$data = array(1, 2, 3, 4, 5);
$sa = new sample($data);
foreach ($sa AS $key => $row) {
echo $key, ' ', $row, '<br />';
}

?>

适用范围

  • 使用返回迭代器的包或库时(如PHP5中的SPL迭代器)
  • 无法在一次的调用获取容器的所有元素时
  • 要处理数量巨大的无素时(数据库中的表以GB计的数据)
  • ……

举例

一般是使用foreach来使用迭代器,下面整理了一下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php   
class sample implements Iterator
{
private $_items = array(1,2,3,4,5,6,7);

public function __construct() {
;//void
}
public function rewind() { reset($this->_items); }
public function current() { return current($this->_items); }
public function key() { return key($this->_items); }
public function next() { return next($this->_items); }
public function valid() { return ( $this->current() !== false ); }
}

$sa = new sample();
foreach($sa as $key => $val){
print $key . "=>" .$val;
}
?>