首页 > 其他 > 详细

SPL基础接口

时间:2020-03-11 18:55:40      阅读:54      评论:0      收藏:0      [点我收藏+]

Iterator 迭代器接口

SPL规定,所有实现了Iterator接口的class,都可以用在foreach Loop中。Iterator接口中包含5个必须实现的方法:

interface Iterator extends Traversable{
    //返回当前元素
    public mixed current ( void );
    
    //返回当前元素的键
    public scalar key ( void );
    
    //向前移动到下一个元素
    public void next ( void );
    
    //返回到迭代器的第一个元素
    public void rewind ( void );
    
    //检查当前位置是否有效
    public boolean valid ( void );
}

示例:

class MyIterator implements Iterator
{
    private $position = 0;
    private $array = array(
        "firstelement",
        "secondelement",
        "lastelement",
    );

    function rewind() {
        var_dump(__METHOD__);
        $this->position = 0;
    }

    function current() {
        var_dump(__METHOD__);
        return $this->array[$this->position];
    }

    function key() {
        var_dump(__METHOD__);
        return $this->position;
    }

    function next() {
        var_dump(__METHOD__);
        ++$this->position;
    }

    function valid() {
        var_dump(__METHOD__);
        return isset($this->array[$this->position]);
    }

}

$it = new MyIterator;

foreach($it as $key => $value) {
    var_dump($key, $value);
    echo "\n";
}

 

ArrayAccess 数组式访问接口

实现ArrayAccess接口,可以使得object像array那样操作。ArrayAccess接口包含四个必须实现的方法:

interface ArrayAccess {
    //检查一个偏移位置是否存在 
    public mixed offsetExists ( mixed $offset  );
    
    //获取一个偏移位置的值 
    public mixed offsetGet( mixed $offset  );
    
    //设置一个偏移位置的值 
    public mixed offsetSet ( mixed $offset  );
    
    //复位一个偏移位置的值 
    public mixed offsetUnset  ( mixed $offset  );
}

示例:

class obj implements arrayaccess {
    private $container = array();
    public function __construct() {
        $this->container = array(
            "one"   => 1,
            "two"   => 2,
            "three" => 3,
        );
    }
    public function offsetSet($offset, $value) {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }
    public function offsetExists($offset) {
        return isset($this->container[$offset]);
    }
    public function offsetUnset($offset) {
        unset($this->container[$offset]);
    }
    public function offsetGet($offset) {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }
}

$obj = new obj;
var_dump($obj);exit;
var_dump(isset($obj["two"]));
var_dump($obj["two"]);
unset($obj["two"]);
var_dump(isset($obj["two"]));
$obj["two"] = "A value";
var_dump($obj["two"]);
$obj[] = ‘Append 1‘;
$obj[] = ‘Append 2‘;
$obj[] = ‘Append 3‘;
print_r($obj);

IteratorAggregate 聚合式迭代器接口

假设对象A实现了上面的ArrayAccess接口,这时候虽然可以像数组那样操作,却无法使用foreach遍历,除非实现了前面提到的Iterator接口。

另一个解决方法是,有时会需要将数据和遍历部分分开,这时就可以实现IteratorAggregate接口。它规定了一个getIterator()方法,返回一个使用Iterator接口的object。

IteratorAggregate extends Traversable {
    /* 获取一个外部迭代器 */
    abstract public Traversable getIterator ( void )
}

示例:

<?php
class myData implements IteratorAggregate {
    public $property1 = "Public property one";
    public $property2 = "Public property two";
    public $property3 = "Public property three";

    public function __construct() {
        $this->property4 = "last property";
    }

    public function getIterator() {
        return new ArrayIterator($this);
    }
}

$obj = new myData;

foreach($obj as $key => $value) {
    var_dump($key, $value);
    echo "\n";
}
?>

注意:
虽然都继承自Traversable,但这是一个无法在 PHP 脚本中实现的内部引擎接口。我们直接使用IteratorAggregate 或 Iterator 接口来代替它。

RecursiveIterator

  • 可以对多层结构的迭代器进行迭代,比如遍历一棵树
  • 所有具有层次结构特点的数据都可以用这个接口遍历,如文件夹
  • 关键方法
    • hasChildren方法可以用于判断当前节点是否存在子节点
    • getChildren方法用于得到当前节点子节点的迭代器
  • SPL中实现该接口的类
  • RecursiveArrayIterator,RecuriveCachingIterator等以Recurive开头的类都可以进行多层次结构化遍历

这个接口用于遍历多层数据,它继承了Iterator接口,因而也具有标准的current()、key()、next()、 rewind()和valid()方法。同时,它自己还规定了getChildren()hasChildren()方法。The getChildren() method must return an object that implements RecursiveIterator。

SeekableIterator

  • SeekableIterator
    • 可以通过seek方法定位到集合里面的某个特定的元素
    • seek方法的参数是元素的位置,从0开始计算
  • SPL中实现该接口的类
    • ArrayIterator、DirectoryIterator、FilesystemIterator、GlobIterator、RecursiveArrayIterator、RecursiveDirectoryIterator

SeekableIterator接口也是Iterator接口的延伸,除了Iterator的5个方法以外,还规定了seek()方法,参数是元素的位置,返回该元素。如果该位置不存在,则抛出OutOfBoundsException。

Countable

这个接口规定了一个count()方法,返回结果集的数量。

<?php 
//Example One, BAD 技术分享图片 

class CountMe 
{ 

    protected $_myCount = 3; 

    public function count() 
    { 
        return $this->_myCount; 
    } 

} 

$countable = new CountMe(); 
echo count($countable); //result is "1", not as expected 
echo $countable->count;//result is "3"
//Example Two, GOOD 技术分享图片 

class CountMe implements Countable 
{ 

    protected $_myCount = 3; 

    public function count() 
    { 
        return $this->_myCount; 
    } 

} 

$countable = new CountMe(); 
echo $countable->count();//result is "3"
echo count($countable); //result is "3" as expected 
?>

OuterIterator 迭代器接口

  • OuterIterator如果想对迭代器进行一定的处理之后再返回,可以用这个接口
  • IteratorIterator类是OuterIterator的实现,扩展的时候可以直接继承IteratorIterator
<?php


/**
*  
*/
class outerImpl extends IteratorIterator
{

    public function current()
    {
        # code...
        return parent::current().‘_tail‘;
    }
    public function key()
    {
        return ‘pre_‘.parent::key();
    }
}

$array = [‘value1‘,‘value2‘,‘value3‘,‘value4‘];

$outerObj = new outerImpl(new ArrayIterator($array));

foreach ($outerObj as $key => $value) {
    # code...
    echo ‘++‘.$key.‘-‘.$value.PHP_EOL;
}

SPL基础接口

原文:https://www.cnblogs.com/xiaobingch/p/12464529.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!