场景:平常工作中写的都是业务模块,很少会去实现这样的接口,但是在框架里面用的倒是很多。
1. Traversable(遍历)接口
该接口不能被类直接实现,如果直接写了一个普通类实现了该遍历接口,是会直接报致命的错误,提示使用 Iterator(迭代器接口)或者 IteratorAggregate(聚合迭代器接口)来实现,这两个接口后面会介绍;所有通常情况下,我们只是会用来判断该类是否可以使用 foreach 来进行遍历;
class Test implements Traversable
{
}
上面这个是错误示范,该代码会提示这样的错误:
Fatal error: Class Test must implement interface Traversable as part of either Iterator or
IteratorAggregate in Unknown on line 0
上面的大致意思是说如要实现这个接口,必须同Iterator或者IteratorAggregate来实现
正确的做法:
当我们要判断一个类是否可以使用foreach来进行遍历,只需要判断是否是traversable的实例
class Test
{
}
$test = new Test;
var_dump($test instanceOf Traversable);
2. Iterator(迭代器)接口
迭代器接口其实实现的原理就是类似指针的移动,当我们写一个类的时候,通过实现对应的 5 个方法:key(),current(),next(),rewind(),valid(),就可以实现数据的迭代移动,具体看以下代码
<?php
class Test implements Iterator
{
private $key;
private $val = [
'one',
'two',
'three',
];
public function key()
{
return $this->key;
}
public function current()
{
return $this->val[$this->key];
}
public function next()
{
++$this->key;
}
public function rewind()
{
$this->key = 0;
}
public function valid()
{
return isset($this->val[$this->key]);
}
}
$test = new Test;
$test->rewind();
while($test->valid()) {
echo $test->key . ':' . $test->current() . PHP_EOL;
$test->next();
}
## 该输出结果 :
0: one
1: two
2: three
看了这个原理我们就知道,其实迭代的移动方式:rewind()-> valid()->key() -> current() -> next() -> valid()-> key() ....-> valid();
好的,理解了上面,我们打开Iterator的接口,发现它是实现了Traversable(遍历)接口的,接下来我们来证明下:
var_dump($test instanceOf Traversable);
结果返回的是true,证明这个类的对象是可以进行遍历的。
foreach ($test as $key => $value){