如果想在自定义类中重载迭代器,就需要执行一些 PHP 预定义的接口。
任何实现 Traversable 接口的类都可以用 foreach 结构遍历。但 Traversable 是一个空的接口而且不能被直接执行。可以执行 Iterator 或者 IteratorAggregate,它们都是从 Traversable 继承而来的。
- <?php
- class NumberSquared implements Iterator {
- private $start, $end, $cur;
- public function __construct($start, $end) {
- $this->start = $start;
- $this->end = $end;
- }
- public function rewind() {
- $this->cur = $this->start;
- }
- public function key() {
- return $this->cur;
- }
- public function current() {
- return pow($this->cur, 2);
- }
- public function next() {
- $this->cur++;
- }
- public function valid() {
- return $this->cur <= $this->end;
- }
- }
- $obj = new NumberSquared(4, 9);
- foreach ($obj as $key => $value) {
- print "The square of $key is $value<br />";
- }
- ?>
可以把类的执行和类的迭代器分离开来,改写上面的代码如下:
- <?php
- class NumberSquared implements IteratorAggregate {
- private $start, $end;
- public function __construct($start, $end) {
- $this->start = $start;
- $this->end = $end;
- }
- public function getIterator() {
- return new NumberSquaredIterator($this);
- }
- public function getStart() {
- return $this->start;
- }
- public function getEnd() {
- return $this->end;
- }
- }
- class NumberSquaredIterator implements Iterator {
- private $obj, $cur;
- function __construct($obj) {
- $this->obj = $obj;
- }
- public function rewind() {
- $this->cur = $this->obj->getStart();
- }
- public function key() {
- return $this->cur;
- }
- public function current() {
- return pow($this->cur, 2);
- }
- public function next() {
- $this->cur++;
- }
- public function valid() {
- return $this->cur <= $this->obj->getEnd();
- }
- }
- $obj = new NumberSquared(4, 9);
- foreach ($obj as $key => $value) {
- print "The square of $key is $value<br />";
- }
- ?>
执行结果都是一样的,如下:
- The square of 4 is 16
- The square of 5 is 25
- The square of 6 is 36
- The square of 7 is 49
- The square of 8 is 64
- The square of 9 is 81
参考来源:《PHP权威编程》的第4章(PHP 5高级面向对象编程和设计模式)部分