使用迭代模式遍历所有的对象的时候,都必须实现Traversable(遍历)接口。但是Traversable是一个内部的类,只有用c语言编写的类才可以实现Traversable实现。如果我们在自定义的 类中实现它,会报错。那么我们要实现对象的遍历,就必须通过Iterator或者IteratorAggregate接口实现Traversable接口。

一,首先说说Iterator接口

它是在c语言中定义的,都是抽象方法,所以我们在实现接口的时候,就必须定义这些方法,代码如下:

Iterator extends Traversable {
/* 方法 */
abstract public mixed current ( void )
abstract public scalar key ( void )
abstract public void next ( void )
abstract public void rewind ( void )
abstract public boolean valid ( void )
}

接着我们在PHP中实现接口Iterator,代码如下:

//自定义类实现接口Iterator
class myIterator implements Iterator {
private $position = 0;
private $array = array(
"firstelement",
"secondelement",
"lastelement",
); public function __construct() {
$this->position = 0;
}
//定义rewind()-将数组指针移动到数组的开头位置
function rewind() {
var_dump(__METHOD__);
$this->position = 0;
}
//定义current()-返回当前的值
function current() {
var_dump(__METHOD__);
return $this->array[$this->position];
}
//定义可以key()-返回当前的键值
function key() {
var_dump(__METHOD__);
return $this->position;
}
//定义next()-将数组指针向前进一位指向下一个数组元素
function next() {
var_dump(__METHOD__);
++$this->position;
}
//定义valid()-确定当前元素是否存在,并且必须在next()和rewind()方法之后才可以调用
function valid() {
var_dump(__METHOD__);
return isset($this->array[$this->position]);
}
} $it = new myIterator; foreach($it as $key => $value) {
var_dump($key, $value);
echo "\n";
}

代码运行结果如下:

大家可能不明白,为什么利用foreach()就可以循环打印出类的属性,程序执行的顺序看我的注释,再次提醒大家注意
“定义valid()-确定当前元素是否存在,并且必须在next()和rewind()方法之后才可以调用”。

string(18) "myIterator::rewind" ----------程序开始执行首先调用rewind()函数,将数组指针移到数组开头位置
string(17) "myIterator::valid" ----------接着调用valid()当前元素是否存在,这个函数每次紧跟rewind()和next()函数被调用
string(19) "myIterator::current" ----------调用current()获取当前的值
string(15) "myIterator::key" ----------调用key()获取当前位置的键值
int(0)
string(12) "firstelement"

string(16) "myIterator::next" ----------上一步获取当前位置,肯定要调用next(),获取下一个位置的指针,即指针向下移动
string(17) "myIterator::valid" ----------判断当前元素是否存在
string(19) "myIterator::current" ----------如果存在,获取当前元素
string(15) "myIterator::key" ----------获取当前键值,为了下一步指针向前移动
int(1)
string(13) "secondelement"

string(16) "myIterator::next" ---------指针指向下一个元素
string(17) "myIterator::valid" ---------判断当前元素是否存在
string(19) "myIterator::current" ---------元素存在,获取当前的元素
string(15) "myIterator::key" ---------获取当前键值
int(2)
string(11) "lastelement"

string(16) "myIterator::next" ---------指针指向下一个位置
string(17) "myIterator::valid" ---------判断当前位置是否有值。如果有获取值,没有就结束遍历

二 ,IteratorAggregate接口

是用来将Iterator接口要求实现的5个方法委托给其他类(比如ArrayIterator)来实现

(1) ArrayIterator接口:允许从PHP数组中创建一个迭代器。上面我们通过实现Iterator接口实现迭代器,但是ArrayIterator可以直接跳过,实现同样的功能。

(2)当ArrayIterator迭代器和IteratorAggregate类一起使用的时候,直接免去Iterator创建方法的工作,所以在实现IteratorAggregate类中的方法getIterator时候,返回一个ArrayIterator接口就好。

(3) IteratorAggregate的c语言实现代码:定义抽象方法getIterator,所以实现接口的时候,必须定义该方法

IteratorAggregate extends Traversable {
/* 方法 */
abstract public Traversable getIterator ( void )
}
class myData implements IteratorAggregate {
public $property1 = "Public property one";
public $property2 = "Public property two";
public $property3 = "Public property three"; public function __construct() {
$this->property4 = "last property";
}
//定义方法----getIterator()---返回一个Iterator类的实例
public function getIterator() {
//ArrayIterator()接口可以创建一个Iterator实例
return new ArrayIterator($this);
}
} $obj = new myData(); foreach($obj as $key => $value) {
var_dump($key, $value);
echo "\n";
}

运行如下:
string(9) "property1"
string(19) "Public property one"

string(9) "property2"
string(19) "Public property two"

string(9) "property3"
string(21) "Public property three"

string(9) "property4"
string(13) "last property"

 

PHP迭代器:Iterator和IteratorAggregate的更多相关文章

  1. 用struts2标签如何从数据库获取数据并在查询页面显示。最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变量。

    最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变 ...

  2. VC++ 迭代器 iterator, const_iterator, const iterator

    迭代器 iterator, const_iterator, const iterator 迭代器iterator的作用类似于指针. (1)iterator只有针对制定<类型>的容器才有效. ...

  3. 迭代器iterator

    现在接着上篇的,写一来标识vector 的元素的对象迭代器iterator: 还是通过具体代码举例: 下面我讲了一个我暑期团队的故事哦~~: #include<iostream> #inc ...

  4. c++中的迭代器 iterator

    迭代器iterator的作用类似于指针. iterator只有针对制定<类型>的容器才有效.例如: vector<int> vec; vector<int>::it ...

  5. Python的迭代器(iterator)和生成器(constructor)

    一.迭代器(iterator) 1.迭代器的概述 在Python中,for循环可以用于Python中的任何类型,包括列表.元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器 迭代器 ...

  6. 设计模式 - 迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释

    迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考迭代器模式(ite ...

  7. Java 实现迭代器(Iterator)模式

    类图 /** * 自己定义集合接口, 相似java.util.Collection * 用于数据存储 * @author stone * */ public interface ICollection ...

  8. C++迭代器 iterator【转】

    1. 迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型.(1) 每种容器类型都定义了自己的迭代器类型,如vector:vector<int>::iterator iter ...

  9. Java迭代器Iterator

    之前我们实现了迭代器模式,很多编程语言实际上已经内置了迭代器类,比如Java就为我们实现了迭代器Iterator.我们首先来看Iterator中的源码. 通过JDK源码我们发现Iterator是一个接 ...

随机推荐

  1. YCD 软件更新方法

    备份Messenger的数据库和Player的Chainmail数据 Upgrade process in Cnario is quite simple, uninstall old version ...

  2. 该错误的解决办法:Incorrect string value: '\xF0\x9F...' for column 'XXX' at row 1

    Incorrect string value: '\xF0\x9F...' for column 'XXX' at row 1 这个问题,原因是UTF-8编码有可能是两个.三个.四个字节.Emoji表 ...

  3. 洛谷 P1088 火星人

    https://www.luogu.org/problemnew/show/P1088 这个题一开始是很蒙的 感觉很麻烦,每次都要交换balabala..... 后来才知道有这么一个神奇的stl 真是 ...

  4. LODOP中ADD_PRINT_TABLE、HTM、HTML表格自动分页测试

    LODOP中超文本超过打印项高度会自动分页,那么对于超大行,该行处在分页高度位置会怎样呢?本文用来测试一下三个语句对html中table中超大行在分页高度位置的处理. 测试结果:ADD_PRINT_T ...

  5. Qin Shi Huang's National Road System HDU - 4081(树形dp+最小生成树)

    Qin Shi Huang's National Road System HDU - 4081 感觉这道题和hdu4756很像... 求最小生成树里面删去一边E1 再加一边E2 求该边两顶点权值和除以 ...

  6. 如何从官网下载 Google Chrome 离线安装包

    1.打开 Chrome 浏览器主页:http://www.google.cn/chrome 2.地址栏最后的网址是这样的:http://www.google.cn/chrome/browser/des ...

  7. 关于sha1加密与md5加密

    1.区别 Hash,一般翻译做"散列",也有直接音译为"哈希"的,就是把任意长度的输入,变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映射,也就是, ...

  8. redis持久化和主从同步

    redis持久化rdb与aof 简介 Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题,Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的 ...

  9. Java斗地主案例、异常和自定义异常整理

    模拟斗地主洗牌发牌 1.1 案例介绍 按照斗地主的规则,完成洗牌发牌的动作. 具体规则: 1. 组装54张扑克牌 2. 将54张牌顺序打乱 3. 三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张 ...

  10. Mysql SQL注入漏洞

    学习网址:http://www.cnblogs.com/rush/archive/2011/12/31/2309203.html https://www.cnblogs.com/sdya/p/4568 ...