• 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数组转换为迭代器,然后用于其他内置的迭代器进行处理。

  • 相关阅读:
    DB设计原则
    英文地址[转]
    ICollection
    雅虎优化14条
    vue过滤器
    php中echo(),print(),print_r()之间的区别
    jQ中对attr()方法的理解
    浅析call和apply的不同
    浅析call和apply
    PHP是弱类型语言,自动转换,强制转换
  • 原文地址:https://www.cnblogs.com/mitang/p/4106952.html
Copyright © 2020-2023  润新知