最近BI项目重新改造,原有数据是通过PHP循环分析数据,更改后,想使用迭代器。这里我将PHP的迭代器总结下
迭代器有时又称光标(cursor)是程式设计的软件设计模式,可在容器物件(container,例如list或vector)上遍访的接口,设计人员无需关心容器物件的内容。就好比SQL中的游标原理一样,遍历访问。
PHP语言与其它语言不同,如Java、python等语言就将Iterator完美的整合,我们称隐式迭代器(implicit iterator)。PHP5菜开始支持接口,所以在这个时候才内置了Iterator接口。所以在PHP总,你定义了一个类,并实现了Iterator接口,那么你的这个类对象就是ZEND_ITER_OBJECT,否则就是ZEND_ITER_PLAIN_OBJECT。
对于ZEND_ITER_PLAIN_OBJECT的类,foreach会通过HASH_OF获取该对象的默认属性数组,然后对该数组进行foreach。
而对于ZEND_ITER_OBJECT的类对象,则会通过调用对象实现的Iterator接口相关函数来进行foreach。
看下面的例子,我们实际的代码来说明:
<?php
/**
* Iterator模式的简单实现
*/
class mysample impplements Iterator {
private $_items;
public function __construct(&$data) { // 使用引用
$this->_items = $data;
}
// 获取指向现在的
public function current() {
return current($this->_items);
}
// 指向下一个
public function next() {
next($this->_items);
}
// 获取当前指向的KEY
public function key() {
return key($this->_items);
}
// 重置
public function rewind() {
reset($this->_items);
}
// 是否有效数据,当前是否存在合法
public function valid() {
return ($this->_current() != FALSE);
}
}
// 测试
$data = array(1, 2, 3, 4, 5);
$sa = new mysample($data);
foreach ($sa as $k => $v) {
echo $key, ' ', $v, '<br />';
}
?>
不同的迭代器有不同的接口,在PHP中:Next()(移动到下一个元素),corrent()(返回当前元素),valid()(检查迭代结尾),rewind()(从头重新开始),key()(返回当前元素的索引)。当然你可以自己写适合自己用的迭代器,也可以用系统中的迭代器。
在PHP中while循环是最常使用
<?php
// 如上面的
while ($iterator->valid()) {
$element=$iterator->current(); // 获取当前元素
$iterator->next();
}
?>
上面的代码是不是非常简洁方便呢?
使用迭代器来分析数据非常重要,这里有两个主要原因
1、利用PHP的迭代器可以利用面向对象实现常见的数据结构,例如:列表、栈堆、队列等。可以实现大部分数据结构
2、使用方便,灵活;防止死循环等不符合逻辑的点。