PHP 对象迭代功能详解
这两天在翻看PHP手册,进一步对PHP类加以理解和掌握。本文是对“PHP对象迭代”做相关总结和学习。
PHP5提供了一种迭代对象的功能,就如同使用数组一样,可以通过使用foreach循环来遍历对象当中的属性。通常,我们使用foreach迭代对象,仅仅可以遍历外部可见的属相值(可见性为public的类成员变量)。
<?php class MyClass { public $var1 = ‘value 1‘; public $var2 = ‘value 2‘; public $var3 = ‘value 3‘; protected $protected = ‘protected var‘; private $private = ‘private var‘; function iterateVisible() { echo "MyClass::iterateVisible:\n"; foreach($this as $key => $value) { print "$key => $value\n"; } } } $class = new MyClass(); foreach($class as $key => $value) { print "$key => $value\n"; } echo "\n"; $class->iterateVisible(); ?>
以上示例输出如下:
var1 => value 1 var2 => value 2 var3 => value 3 MyClass::iterateVisible: var1 => value 1 var2 => value 2 var3 => value 3 protected => protected var private => private var
简单的foreach虽然也能够完成对象的遍历功能,但是如果需要使用对象遍历功能,我们可能需要实现Iterator接口或者IteratorAggregate接口达到更好的遍历效果。
Iterator 与 IteratorAggregate接口实际都实现了另一个接口Traversable。有关Traversable接口内容,可参看Traversable官方文档 和我翻译文章 正确理解PHP Traversable 接口
实现Iterator接口
Iterator接口,可在内部迭代自己的外部迭代器或类的接口
Iterator接口定义了以下抽象的方法:
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 ) }
实现Iterator接口的类MyIterator。我们需要实现所有Iterator接口,未实现的方法体
class MyIterator implements Iterator{ private $_var = array( "firstelement", "secondelement", "lastelement", ); public function __construct(){} public function rewind(){ echo __METHOD__ ,‘<br/>‘; return reset($this->_var); } public function current(){ echo __METHOD__ ,‘<br/>‘; $current = current($this->_var); return $current; } public function next(){ echo __METHOD__ ,‘<br/>‘; $next = next($this->_var); return $next; } public function key(){ echo __METHOD__ ,‘<br/>‘; $key = key($this->_var); return $key; } public function valid(){ echo __METHOD__ ,‘<br/>‘; $valid = $this->current() !== false; return $valid; } } $myIterator = new MyIterator(); foreach($myIterator as $key => $value){ echo $key , ‘ ----- ‘, $value ,‘<br/>‘; }运行结果:
MyIterator::rewind MyIterator::valid MyIterator::current MyIterator::current MyIterator::key 0 ----- firstelement MyIterator::next MyIterator::valid MyIterator::current MyIterator::current MyIterator::key 1 ----- secondelement MyIterator::next MyIterator::valid MyIterator::current MyIterator::current MyIterator::key 2 ----- lastelement MyIterator::next MyIterator::valid MyIterator::current从运行结果我们可以很清晰的看到Iterator接口中方法的调用顺序如下图所示
1:重置指针 rewind()
2:判断是否存在属性 valid()
3:存在获取当前值 current()
4:获取当前值的键名 key()
第二次以后迭代
1:获取对象内下一个属性 next();
2:判断是否存在属性 valid()
3:存在获取当前值 current()
4:获取当前值的键名 key()
实现IteratorAggregate接口
IteratorAggregate接口 :创建外部迭代器的接口。
Iterator接口定义了以下抽象的方法:
IteratorAggregate extends Traversable { /* 方法 */ abstract public Traversable getIterator ( void ) }
定义实现Iteratorgate类MyCollection
<?php class MyCollection implements IteratorAggregate { private $items = array(); private $count = 0; // Required definition of interface IteratorAggregate public function getIterator() { return new MyIterator($this->items); } public function add($value) { $this->items[$this->count++] = $value; } } $coll = new MyCollection(); $coll->add(‘value 1‘); $coll->add(‘value 2‘); $coll->add(‘value 3‘); foreach ($coll as $key => $val) { echo "key/value: [$key -> $val]\n\n"; } ?>运行结果如下:
rewinding current: value 1 valid: 1 current: value 1 key: 0 key/value: [0 -> value 1] next: value 2 current: value 2 valid: 1 current: value 2 key: 1 key/value: [1 -> value 2] next: value 3 current: value 3 valid: 1 current: value 3 key: 2 key/value: [2 -> value 3] next: current: valid:
通过实现IteratorAggregate接口,我们可以简单的实现getIterator()方法,达到遍历对象的功能
扩展阅读
关于一笔试题(Iterator模式)
正确理解PHP Traversable 接口
本文出自 “柳公子” 博客,请务必保留此出处http://phpnotes.blog.51cto.com/5625189/1358889
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。