SPL 是 PHP 的标准库,定义了一些类和接口,让 PHP 的功能更加丰富。
早就计划对 SPL 进行系统的学习,这里对学习做一些基本的笔记。
先说遍历,能够遍历的类都要实现 Traversable 接口,但是 Traversable 接口不能被单独实现,只能通过实现他的子接口 Iterator 和 IteratorAggregate 来实现 Traversable 接口。因此只要实现了这两个接口中的任何一个,就能让对象用foreach
进行遍历。(从 PHP5 开始,任何类如果未实现 Traversable,对类的遍历会转化为对类的公共属性的遍历)。
Iterator 接口 所有实现了 Iterator 接口的类,都可以进行遍历。实现 Iterator 接口需要实现 5 个方法。
1 2 3 4 5 6 7 8 9 10 11 12 interface Iterator extends Traversable { //返回迭代器当前元素 public function current(); //移动迭代器位置到下一个 public function next(); //返回返回迭代器当前元素的键名 public function key(); //检查迭代器当前位置是否有效 public function valid(); //恢复迭代器的初始位置 public function rewind(); }
举个栗子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class MenIterator implements Iterator { public $men = []; public $position = 0; public function current() { return $this->men[$this->position]; } public function next() { $this->position++; } public function rewind() { $this->position = 0; } public function valid() { return isset($this->men[$this->position]); } public function key() { return $this->position; } }
通过此接口可以灵活地对任何对象实现遍历操作。
IteratorAggregate IteratorAggregate 接口和 Iterator 一样,实现了 IteratorAggregte 接口的类也可以进行遍历。Iterator 隐性的通过 getIterator
方法返回一个迭代器,本质上仍然相当于实现了 Iterator 接口。使用这种方式符合“多用组合,少用继承”的面向对象设计思想。
1 2 3 interface IteratorAggregate extends Traversable { public function getIterator(); }
getIterator 方法必须返回一个 Iterator 实例。
1 2 3 4 5 6 7 8 9 10 11 class Men { public function __construct(){ //MenIterator见上例 $this->men = new MenIterator; $this->men->men = ["a", "b"]; } public function getIterator(){ return $this->men; } }
这样,Men 类的实例便可以使用 foreach
进行遍历了。