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基础接口的更多相关文章

  1. MMORPG大型游戏设计与开发(服务器 AI 基础接口)

    一个模块都往往需要统一的接口支持,特别是对于非常大型的模块,基础结构的统一性非常重要,它往往决定了其扩展对象的通用性.昨天说了AI的基本概述以及组成,作为与场景模块中核心一样重要的地位,基础部分的设计 ...

  2. .net微信公众号开发——基础接口

    作者:王先荣    本文讲述微信公众号开发中基础接口的使用,包括以下内容:    (1)获取许可令牌(AccessToken):    (2)获取微信服务器地址:    (3)上传.下载多媒体文件:  ...

  3. php获取微信基础接口凭证Access_token

    php获取微信基础接口凭证Access_token的具体代码,供大家参考,具体内容如下 access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token.开发者需要进 ...

  4. face_recognition 基础接口

    face_recognition 基础接口 face_recognition使用世界上最简单的人脸识别库,在Python或命令行中识别和操作人脸. 使用dlib最先进的人脸识别技术构建而成,并具有深度 ...

  5. ABP开发框架前后端开发系列---(6)ABP基础接口处理和省份城市行政区管理模块的开发

    最近没有更新ABP框架的相关文章,一直在研究和封装相关的接口,总算告一段落,开始继续整理下开发心得.上次我在随笔<ABP开发框架前后端开发系列---(5)Web API调用类在Winform项目 ...

  6. PHP 面向对对象基础(接口,类)

    介绍PHP面向对象的基础知识 1. 接口的定义interface ,类定义class,类支持abstract和final修饰符,abstract修饰为抽象类,抽象类 不支持直接实例化,final修饰的 ...

  7. Java 基础 接口和多态

    接口 接口的概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”. 接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成.这样将功能的 ...

  8. JDBC的基础接口及其用法

    JDBC基础 所谓JDBC即是:Java DataBase Connectivity,java与数据库的连接.是一些用来执行SQL语句的Java API. 我们进行JDBC的编程,主要常用的几个概念: ...

  9. Python基础-接口与归一化设计、抽象类、继承顺序、子类调用父类,多态与多态性

    一.接口与归一化设计 Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能). 由 ...

随机推荐

  1. JS面向对象编程之对象

    在AJAX兴起以前,很多人写JS可以说都是毫无章法可言的,基本上是想到什么就写什么,就是一个接一个的函数function,遇到重复的还得copy,如果一不小心函数重名了,还真不知道从何开始查找错误,因 ...

  2. jQuery学习(三)

    事件 on方法可以将一个事件绑定在jQuery对象上,当你的操作触发了这些事件时,便会调用你所绑定的函数. 例如,给某个超链接绑定点击事件. <head> <meta http-eq ...

  3. idea jdk版本切换

    为什么80%的码农都做不了架构师?>>>   打开file-peoject structure,或者 改完project后,点击models里面的sources 和dependenc ...

  4. HDU1873 看病要排队【模拟+优先队列】

    看病要排队 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  5. axis2 411

    返回411加个这个就行了 _operationClient.getOptions().setProperty(HTTPConstants.CHUNKED, false); 本文转自 cd1989929 ...

  6. 翻转单词顺序 VS 左旋转字符串

    全部内容来自<剑指offer>. 题目一: 输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变.为简单起见,标点符号和普通字符一样处理.例如输入字符串“I am a stude ...

  7. 算法——Java实现队列

    顺序队列: 概念: 队列是一种先进先出的线性表,只允许在一端插入,另一端删除.允许插入的一端称为队尾,允许删除的一端称为队头 顺序队列的实现: import org.junit.jupiter.api ...

  8. Phoenix and Distribution(字典序贪心)

    \(给定一串字母,分成k份,使得最大字典序最小.(字母可以任意组合)\) \(------------------------------issue~------------------------\ ...

  9. M - Little Pony and Harmony Chest 状压dp

    M - Little Pony and Harmony Chest 怎么感觉自己越来越傻了,都知道状态的定义了还没有推出转移方程. 首先这个a的范围是0~30   这里可以推出 b数组的范围 0~60 ...

  10. bootstrap4中bootstrap_treeview不显示图标原因以及解决办法

    1.bootstrap4中bootstrap_treeview不显示图标原因 查看过大神的博客,经过自己试验,插件依赖: bootstrap/3.3.7 jquery/3.3.1 <link h ...