1、php提供了一个语法结构用于遍历数组和对象  foreach

2、而foreach则不能直接遍历对象里面的属性,需要通过迭代器(预定义接口 Iterator)

  • 先来看这两条,首先看第1条,

    • foreach可以遍历数组和对象。遍历数组大家都知道,foreach遍历对象可能就会有疑问了。
    • 刚开始我以为遍历对象是将对象中所有的属性和方法都遍历出来,后来发现不是。
    • foreach遍历对象时,仅遍历对象属性。对象的属性是一个集合数组, 因此foreach遍历对象时就是遍历对象中所有的公开属性,private遍历不到。
  • 再来看第2条,表述有歧义,

    • foreach则不能直接遍历对象里面的属性,这句话中对象里的属性是指单个属性,还是指所有属性?
    • 经过对第一条的分析,我们知道foreach可以遍历对象中所有公开的属性,当然public属性是不合理的,这里我们只考虑实现可能性。
    • 然后我又尝试了一下,foreach遍历对象中指定的单个属性(public),也没问题,此处可以通过一个public方法获得该属性,从而将属性设置为private。
  • 看一下该博客中给出的示例代码, 实现了Iterator 接口中的5个抽象方法。

class Season implements Iterator{
private $position = 0;//指针指向0
private $arr = array('春','夏','秋','冬');
public function rewind(){
return $this -> position = 0;
}
public function current(){
return $this -> arr[$this -> position];
}
public function key(){
return $this -> position;
}
public function next() {
++$this -> position;
} public function valid() {
return isset($this -> arr[$this -> position]);
}
}
$obj = new Season;
foreach ($obj as $key => $value) {
echo $key.':'.$value."\n";
}
?> 结果: 0:春
1:夏
2:秋
3:冬
PHP5开始支持了接口, 并且内置了Iterator接口, 所以如果你定义了一个类,并实现了Iterator接口,那么你的这个类对象就是ZEND_ITER_OBJECT,否则就是ZEND_ITER_PLAIN_OBJECT。
对于ZEND_ITER_PLAIN_OBJECT的类,foreach会通过HASH_OF获取该对象的默认属性数组,然后对该数组进行foreach,而对于ZEND_ITER_OBJECT的类对象,则会通过调用对象实现的Iterator接口相关函数来进行foreach。
  • 下面这句话是迭代器的定义,字字玑珠, 细细品味
来看下迭代器的定义,那就是提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部显示。它可帮助构造特定的对象,那些对象能够提供单一标准接口循环或迭代任何类型的可计数数据
  • 再来看看迭代器内部的五个方法
Iterator::current — Return the current element 返回当前元素
Iterator::key — Return the key of the current element 返回当前元素的键
Iterator::next — Move forward to next element 移向下一个元素
Iterator::rewind — Rewind the Iterator to the first element 重新回到第一个元素
Iterator::valid — Checks if current position is valid 检查当前位置的有效性
  • 看过了第一位博主的例子, 下面再看看第二位博主给出的实例
class MyIterator implements Iterator
{
private $var = array(); public function __construct($array)
{
if (is_array($array)) {
$this->var = $array;
}
} public function rewind() {
echo "倒回第一个元素\n";
reset($this->var);
} public function current() {
$var = current($this->var);
echo "当前元素: $var\n";
return $var;
} public function key() {
$var = key($this->var);
echo "当前元素的键: $var\n";
return $var;
} public function next() {
$var = next($this->var);
echo "移向下一个元素: $var\n";
return $var;
} public function valid() {
$var = $this->current() !== false;
echo "检查有效性: {$var}\n";
return $var;
}
} $values = array(1,2,3);
$it = new MyIterator($values);
foreach ($it as $k => $v) {
print "此时键值对 -- key $k: value $v\n\n";
}

  • 在这里,我们向实现迭代器接口的类中传入了一个数组变量,生成了一个对象,专门用来遍历。

  • 我们还可以在类的内部定义一些其他的操作,但从设计模式来讲,最好分开,不要违背单一职责原则,根据场景进行区分。

  • 这样可以向我们的迭代器中传入不同的数组进行遍历,

  • 同时当我们想换一种遍历方式时,只需另外建立一个迭代器,根据需求(比如降序遍历)重新实现5个方法的代码就行了。

  • 数据和算法分离,独立发展

  • 附上第二位博主的总结

来看下迭代器的优点:

1.支持多种遍历方式。比如有序列表,我们根据需要提供正序遍历、倒序遍历两种迭代器。用户只需要得到我们的迭代器,就可以对集合执行遍历操作

2.简化了聚合类。由于引入了迭代器,原有的集合对象不需要自行遍历集合元素了

3.增加新的聚合类和迭代器类很方便,两个维度上可各自独立变化

4.为不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上操作

缺点就是迭代器模式将存储数据和遍历数据的职责分离增加新的集合对象时需要增加对应的迭代器类,类的个数成对增加,在一定程度上增加系统复杂度。

它的使用场景,我们可以参考如下几点:

1.访问一个聚合对象内容而无须暴露它的内部显示

2.需要为聚合对象提供多种遍历方式

3.为遍历不同的聚合结构提供一个统一的接口

最后,咱们来看一个网上找的用迭代器模式来实现的一个斐波那契数列。

我们都知道,斐波那契数列通常做法是用递归实现,当然还有其它的方法,咱们这里用PHP的迭代器来实现一个斐波纳契数列,几乎没有什么难度,只是把类里的next()方法重写了一次。注释已经写到代码中,也是相当好理解的,如下:
class Fibonacci implements Iterator {
private $previous = 1;
private $current = 0;
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() {
return true;
}
} $seq = new Fibonacci;
$i = 0;
foreach ($seq as $f) {
echo "$f ";
if ($i++ === 15) break;
} 输出的结果如下: 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610

再次附上原文地址

1:https://www.cnblogs.com/wwjchina/p/7723499.html

2:https://blog.csdn.net/luyaran/article/details/82867878

php迭代器Iterator接口的更多相关文章

  1. 详解 迭代器 —— Iterator接口、 ListIterator接口 与 并发修改异常

    (请关注 本人"Collection集合"博文--<详解 Collection集合>) Iterator接口(迭代器): 概述: 对 collection 进行迭代的迭 ...

  2. 集合元素的遍历操作,使用迭代器Iterator接口

    1.内部的方法:hasNext() 和 next() 推荐的方式: //hasNext():判断是否还有下一个元素while(iterator.hasNext()){ //next():①指针下移 ② ...

  3. Collections+Iterator 接口 | Map+HashMap+HashTable+TreeMap |

    Collections+Iterator 接口 1. Collections 是一个操作 Set.List 和 Map 等集合的工具类 Collections 中提供了大量方法对集合元素进行排序.查询 ...

  4. java - day011 - 集合, ArrayList HashMap,HashSet, Iterator 接口, for-each 循环格式

    集合 ArrayList 丑数: 能被3,5,7整除多次, ArrayList     list 接口             | - ArrayList             | - Linked ...

  5. java集合(2)-Collection与Iterator接口

    1 package com.j1803.collectionOfIterator; 2 import java.util.ArrayList; 3 import java.util.Collectio ...

  6. Iterator接口(迭代器)

    目录 前言 原理 方法 异常 Iterator接口(迭代器) 前言 一般遍历数组都是采用for循环或者增强for,这两个方法也可以用在集合框架,但是还有一种方法是采用迭代器遍历集合框架,它是一个对象, ...

  7. PHP:Iterator(迭代器)接口和生成器

    迭代器 可在内部迭代自己的外部迭代器或类的接口.详情:http://php.net/manual/zh/class.iterator.php 接口摘要 Iterator extends Travers ...

  8. 牛客网Java刷题知识点之Java 集合框架的构成、集合框架中的迭代器Iterator、集合框架中的集合接口Collection(List和Set)、集合框架中的Map集合

    不多说,直接上干货! 集合框架中包含了大量集合接口.这些接口的实现类和操作它们的算法. 集合容器因为内部的数据结构不同,有多种具体容器. 不断的向上抽取,就形成了集合框架. Map是一次添加一对元素. ...

  9. Java之Iterator接口(遍历单列集合的迭代器)

    Iterator接口概述 在程序开发中,经常需要遍历集合中的所有元素.针对这种需求,JDK专门提供了一个接口java.util.Iterator . Iterator 接口也是Java集合中的一员,但 ...

随机推荐

  1. Centos7.4 下cobbler安装及配置

    1.背景介绍 作为运维,在公司经常遇到一些机械性重复工作要做,例如:为新机器装系统,一台两台机器装系统,可以用光盘.U盘等介质安装,1小时也完成了,但是如果有成百台的服务器还要用光盘.U盘去安装,就显 ...

  2. 精通Dubbo——dubbo2.0源码中的设计模式与SPI介绍

    Dubbo源码包介绍当我们从github把Dubbo源码下载下来之后有如下源码包   下面来说明每个包的作用,以便我们有目的的阅读代码 dubbo-admin dubbo管理平台源码包,用来管理dub ...

  3. 硬盘相关合集,以及LVM操作实践

    1. 机器装有两块硬盘,重装系统只找到一块盘,如何解决? 正常装完系统后,运行: a. lsblk查看硬盘信息,这里可以发现还没有使用的另一块盘. b. fdisk或parted给硬盘分区,取决于硬盘 ...

  4. Django前期知识准备

    一. WEB应用 WEB应用程序是一种可以通过WEB访问的应用程序, 程序的最大好处是用户很容易访问应用程序, 用户只需要有浏览器即可, 不需要再安装其他软件. 应用程序有两种模式: C/S, B/S ...

  5. 5种Redis数据结构详解

    本文主要和大家分享 5种Redis数据结构详解,希望文中的案例和代码,能帮助到大家. 转载链接:https://www.php.cn/php-weizijiaocheng-388126.html 2. ...

  6. 爬虫实现51job谁看过我的简历多条记录功能

    默认情况下51job只能看到最近一条记录,查看更多记录需要付费. 本文利用爬虫定时抓取记录,并追加写入到文本的方式获取完整的记录信息. import requests from bs4 import ...

  7. 【计算机视觉】UCLA开源图像检测器

    UCLA (加州大学洛杉矶分校)发布了一个强大的图像检测软件的源码 ,该软件可以非常高速的检测每个图像的细节,例如可用于检测指纹和虹膜,或者用于自动驾驶.通过识别物体的边界进行提取.首先确定一个物体的 ...

  8. 【并行计算-CUDA开发】从熟悉到精通 英伟达显卡选购指南

    举报 说到显卡,就不免令人想到英伟达和AMD两家面向个人消费级和企业级最大的显示芯片生产企业,英伟达和AMD,今天小编为大家简单的介绍一下英伟达的显卡选购方面的攻略,为一些想要购买显卡的用户提供一些参 ...

  9. Tei-Wei Kuo

    一. A Commitment-based Management Strategy for the Performance and Reliability Enhancement of Flash-m ...

  10. 20.采集项目流程篇之清洗数据绑定到hive表中

    先启动hive 在mydb2这个数据库中创建表: create external table mydb2.access(ip string,day string,url string,upflow s ...