SPL学习 迭代器
主要学习内容:
慕课网的spl视频教程
阮一峰SPL学习笔记 http://www.ruanyifeng.com/blog/2008/07/php_spl_notes.html
SPL类详解 http://www.cnblogs.com/ellisonDon/archive/2013/02/26/2932978.html
PHP SPL,被遗落的宝石 http://www.nowamagic.net/librarys/veda/detail/2165
SPL 迭代器:
SPL更多地被看作是一种使object(物体)模仿array(数组)行为的interfaces和classes。
SPL的内容除了这些模仿的的接口和类,还包括了一些具体功能的内置迭代器对象。
1、对象模仿数组,或者拓宽数组的功能。
两个根,ArrayAccess 和 Traversable
ArrayAccess 叫数组式操作,就是[]的使用。
Traversable 是迭代器的主要的接口,但不能直接使用。
生成迭代器的两个接口,都是继承于Traversable
IteratorAggregate 对一个非迭代器对象,用函数getIterator返回迭代器
Iterator 迭代器,最主要
这四个接口在php属于语言层面,用来获得基本的SPL迭代器
//内部不使用数组,实现迭代器 class Fibonacci implements Iterator { private $previous = 0; private $current = 1; private $key = 0; public function current() { return $this->current; } public function key() { return $this->key; } public function next() { // 关键在这里 // 将当前值保存到 $newprevious $newprevious = $this->current; // 将上一个值与当前值的和赋给当前值 $this->current += $this->previous; // 前一个当前值赋给上一个值 $this->previous = $newprevious; $this->key++; } public function rewind() { $this->previous = 1; $this->current = 0; $this->key = 0; } public function valid() { if($this->key>12) return false; return true; } } //内部用数组构建一个迭代器,同时实现了 数组式访问,随即跳转,count计数 class arrFibonacci implements Iterator, ArrayAccess, SeekableIterator, Countable{ private $arr = array(0,1); private $pos = 0; //循环 Iterator public function current() { return $this->arr[$this->pos]; } public function key() { return $this->pos; } public function next() { $this->pos++; if($this->pos > 1 && !isset($this->arr[$this->pos]) ){ $this->arr[$this->pos] = $this->arr[$this->pos-2] + $this->arr[$this->pos-1]; } } public function rewind() { $this->pos = 0; } public function valid() { if($this->pos>=15) return false; return isset($this->arr[$this->pos]); } //数组式访问元素 ArrayAccess function offsetExists($offset) { return isset($this->arr[$offset]); } function offsetGet($offset){ return $this->arr[$offset]; } function offsetSet($offset, $value){ if(isset($this->arr[$offset])) $this->arr[$offset] = $value; } function offsetUnset($offset){ unset( $this->arr[$offset] ); } //跳转 SeekableIterator function seek($position) { echo $position,'<br>'; if ( isset($this->arr[$position]) ) { $this->pos = $position; } } //计数 function count(){ return count( $this->arr ); } //显示,为了验证,不需要对应SPL接口 public function show(){ showarr($this->arr); } } // ArrayAccess 让一个类具有数组式访问模式 class Article implements ArrayAccess { public $title; public $author; public $category; function __construct($title,$author,$category) { $this->title = $title; $this->author = $author; $this->category = $category; } function offsetExists($key) { return array_key_exists($key,get_object_vars($this)); //get_object_vars — 返回由对象属性组成的关联数组 } function offsetSet($key, $value) { if ( array_key_exists($key,get_object_vars($this)) ) { $this->{$key} = $value; } } function offsetGet($key) { if ( array_key_exists($key,get_object_vars($this)) ) { return $this->{$key}; } } function offsetUnset($key) { if ( array_key_exists($key,get_object_vars($this)) ) { unset($this->{$key}); } } } // 让一个类 返回一个迭代器 class arrArticle implements IteratorAggregate { public $arr = array(); function __construct($title,$author,$category) { $this->arr['title'] = $title; $this->arr['author'] = $author; $this->arr['category'] = $category; } //可以用 IteratorAggregate 接口 返回一个 Iterator function getIterator() { return new ArrayIterator( $this->arr ); } }
SPL迭代器的功能,继承于Iterator的接口,扩展迭代器功能
Countable 用内部函数count,为PHP count 函数 提供结果
SeekableIterator 用函数seek来进行跳转 Iterator 数据的当前位置
RecursiveIterator 递归迭代器,需要实现两个函数,hasChildren()判断当前数据是否可以迭代,和getChildren()获得这个子迭代器
OuterIterator 多重迭代器,迭代器包含子迭代器,(注意和IteratorAggregate不同)。可以用函数 getInnerIterator 返回子迭代器,也可以直接使用这个外部迭代器,其自动迭代子迭代器,中间可以做一定更改,功能强大,用途广泛,SPL中很多内置的迭代器实现了这个接口。还有一个实现的类,IteratorIterator ,可以直接使用这个类。
FilterIterator 抽象类,过滤
AppendIterator 连接多个迭代器 串联
MultipleIterator 合并多个迭代器 并联
2、内置迭代器对象
ArrayIterator 数组迭代器 可用于将PHP数组转换为迭代器,然后用于其他内置的迭代器进行处理。