迭代器(iterator)是一种设计模式,它可以使所有复杂数据结构的组件都可以使用循环来访问。
如我们所知,foreach循环可以对数组进行迭代,while循环可以用来读取查询结果,并且php中有对文件夹及文件内容进行迭代的函数。在以上的几种情况中,底层的数据结构是不一样的,但是对他们进行迭代的前提是相同的。
迭代器,就是一种解决方案:无论迭代的是什么数据结构,我们都可以使用通用的代码(通常是foreach)。
在SPL中定义了很多迭代器,例如:
ArrayIterator、RecursiveArrayIterator、LimitIterator和DirectoryIterator
例如,要对文件夹中的文件进行迭代,就可以使用DirectoryIterator类:
$dir = new DirectoryIterator('.'');
foreach ($dir as $item) {
//对文件进行操作的代码
}
DiretoryIterator类在循环中每次迭代都以SplFileObject对象的格式返回数据项,这意味者我们可以使用该类的相关方法进行操作。
接下来举一个例子,由于实现了Iterator接口,我们所写的类的对象就可以在循环中进行迭代。
<?php
class Department implements Iterator {
private $_name;
private $_employees;
private $_position = 0;
function __construct($name) {
$this->_name = $name;
$this->_employees = array();
$this->_position = 0;
}
function addEmployee(Employee $e) {
$this->_employees[] = $e;
echo '员工'.$e->getName().'加入团队'.$this->getName().'<br>';
}
function getName() {
return $this->_name;
}
//以下为实现Iterator接口的方法
function current() {
return $this->_employees[$this->_position];
}
function key() {
return $this->_position;
}
function next() {
$this->_position++;
}
function rewind() {
$this->_position = 0;
}
function valid() {
return isset($this->_employees[$this->_position]);
}
}
class Employee {
private $_name;
function __construct($name) {
$this->_name = $name;
}
function getName() {
return $this->_name;
}
}
$hr = new Department('人力资源部');
$e1 = new Employee('Tom');
$e2 = new Employee('Jack');
$hr->addEmployee($e1);
$hr->addEmployee($e2);
echo '人力资源部员工明细<br>';
foreach ($hr as $e) {
echo '类'.get_class($e).' 员工'.$e->getName().'<br>';
}
?>
运行一下:
通过结果我们可以发现程序段:
foreach ($hr as $e) {
echo '类'.get_class($e).' 员工'.$e->getName().'<br>';
}
进行循环时,所返回的$e是Employee类的对象,这样我们就可以使用类中定义的方法进行操作了。