在讲解生成器之前先介绍一下迭代器:

在 PHP 中,通常情况下遍历数组使用 foreach 来遍历。

如果我们要想让一个对象可以遍历呢?

PHP 为我们提供了 Iterator 接口,只要实现了这个接口,这个对象就可以通过 foreach 来迭代。

例子如下:


class myIterator implements Iterator {
private $index = 0;
private $data = ''; public function __construct($data) {
$this->index = 0;
$this->data = $data;
} function rewind() {
$this->index = 0;
} function current() {
return $this->data[$this->index];
} function key() {
return $this->index;
} function next() {
++$this->index;
} function valid() {
return isset($this->data[$this->index]);
}
} $it = new myIterator(array(
"hello",
"php",
"iterator",
));
foreach($it as $key => $value) {
echo "$key : $value<br>";
}

我们通过foreach遍历 $it 时,PHP 会自己依次调用:

rewind() 重置到第一个元素
valid() 检查当前位置是否有效
current() 返回当前元素
key() 返回当前元素的键
next() 指向下一个元素

生成器是 PHP 5.5 引入的新特性,但是目前貌似很少人用到它。
下面试 PHP 官方文档上对生成器的解释:
生成器提供了一种更容易的方法来实现简单的对象迭代,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低。
生成器允许你在 foreach 代码块中写代码来迭代一组数据而不需要在内存中创建一个数组, 那会使你的内存达到上限,或者会占据可观的处理时间。相反,你可以写一个生成器函数,就像一个普通的自定义函数一样, 和普通函数只返回一次不同的是, 生成器可以根据需要 yield 多次,以便生成需要迭代的值。

为了体现生成器的有点,下面我们定义一个函数来进行比较:


function func1()
{
foreach (range(0, 1000000) as $value){
echo $value;
}
} func1();
// ( ! ) Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 402653192 bytes) in xxx.php on line 5

因为创建如此大的数组到内存中进行迭代,则 PHP 直接提示超出了单个进程的内存限制。

下面我们换做生成器的方式来处理:


function func1()
{
foreach (range(0, 1000000) as $value){
yield $value;
}
} var_dump(func1()); // object(Generator)[1]
foreach (func1() as $value){
echo $value;
}

可以看到我们调用 func1() 返回了一个 Generator 对象,这个对象可以使用 foreach 迭代,每次迭代,PHP 会要求 Generator 实例计算并提供下一个要迭代的值。生成器的优雅体现在每次产出一个值之后,生成器的内部状态都会停顿;向生成器请求下一个值时,内部状态又会恢复。生成器内部的状态会一直在停顿和恢复之间切换,直到抵达函数定义体的末尾或遇到空的return语句为止。

参考链接:
https://laravelacademy.org/po...
http://php.net/manual/zh/lang...

原文地址:https://segmentfault.com/a/1190000016475883

PHP中的 Iterator 与 Generator的更多相关文章

  1. [Python学习]Iterator 和 Generator的学习心得

    [Python学习]Iterator 和 Generator的学习心得 Iterator是迭代器的意思,它的作用是一次产生一个数据项,直到没有为止.这样在 for 循环中就可以对它进行循环处理了.那么 ...

  2. Python Iterator and Generator

    Python Iterator and Generator Iterator ​ 迭代器(Iterator)和可迭代对象(Iterable)往往是绑定的.可迭代对象就是我们平时经常用的list ,st ...

  3. php中trait(性状)与generator(生成器)

    PHP中trait(性状)与generator(生成器) 一.trait (性状) 最近在看Josh Lockhat的<Modern PHP>,这本书很薄.但是其中给出了一个很重要的学习方 ...

  4. RocksDB笔记 - Compaction中的Iterator

    Compaction中的Iterator 一般来说,Compaction的Input涉及两层数据的合并,对于涉及到的每一层数据: 如果是level-0,对level-0的每一个sstable文件建立一 ...

  5. 如何在遍历中使用 iterator/reverse_iterator 删除元素

    如何在遍历中使用 iterator/reverse_iterator 删除元素 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循“署名-非商业用途-保持一致”创作公 ...

  6. 在遍历中使用 iterator/reverse_iterator 进行 Erase 的使用方法

    在遍历中使用 iterator/reverse_iterator 进行 Erase 的使用方法 罗朝辉 (http://blog.csdn.net/kesalin/) 本文遵循"署名-非商业 ...

  7. STL中实现 iterator trail 的编程技巧

    STL中实现 iterator trail 的编程技巧 <泛型编程和 STL>笔记及思考. 这篇文章主要记录在 STL 中迭代器设计过程中出现的编程技巧,围绕的 STL 主题为 (迭代器特 ...

  8. Python3 Iterator and Generator

    Python3 Iterator and Generator iterator  主要是利用 iter 函数 >>> list=[1,2,3,4] >>> it = ...

  9. 关于ArrayList中的iterator返回的事迭代器实例问题。

    Arraylist是一个具体的类,它并没有定义它自己的iterator()方法,,它只是从AbstractList 这个抽象类中继承了iterator()这个方法,而AbstractList 中的it ...

随机推荐

  1. nyoj2-吝啬的国度

    吝啬的国度 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市,他有 ...

  2. BZOJ 3439 Kpm的MC密码 (Trie树+线段树合并)

    题面 先把每个串反着插进$Trie$树 每个节点的子树内,可能有一些节点是某些字符串的开头 每个节点挂一棵权值线段树,记录这些节点对应的原来字符串的编号 查询的时候在线段树上二分即可 为了节省空间,使 ...

  3. [NoiPlus2016]天天爱跑步

    巨坑 树剖学的好啊!---sfailsth 把一段路径拆成两段,向上和S->LCA,向下LCA->T 用维护重链什么的操作搞一下. sfailsth学长真不容易啊...考场上rush了4. ...

  4. groupadd(创建组)重要参数介绍

    -g :值定用户组GID值.除非接 -o 参数(如:groupadd -g 666 -o oldboy),否则ID值必须是唯一的数字(不能为负数). 如果不指定 -g 参数,则默认从500开始 

  5. Swoole 源码分析——基础模块之 Pipe 管道

    前言 管道是进程间通信 IPC 的最基础的方式,管道有两种类型:命名管道和匿名管道,匿名管道专门用于具有血缘关系的进程之间,完成数据传递,命名管道可以用于任何两个进程之间.swoole 中的管道都是匿 ...

  6. 提高生产力:SpringMVC中,使用扩展数据类型TypedMap接收Web请求参数

    在Web项目中,如果前端MVC框架使用的是SpringMVC,可以使用Map接收前端请求参数,比bean要方便很多. 尤其是SpringMVC和Mybatis一起用的时候,用Map大大减少了需要的be ...

  7. 【 ACM-ICPC 2018 沈阳赛区网络预赛 D】Made In Heaven

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 点可以重复走的k短路. [代码] #include <bits/stdc++.h> #define LL long lo ...

  8. Java 接口技术 Interface

    一.什么是接口技术(Interface): //举例中Comparable是一个接口,Employee是一个类 1.接口不是类,而是对类的一组描述,并不给出每个类的具体实现. 2.一个类可以实现多个接 ...

  9. [Beginning SharePoint Designer 2010]Chapter4 发布页面

    本章概要: 1.SharePoint中的Web内容管理 2.SharePoint发布系统的特性 3.SharePoint发布页面的组成 4.母板页 5.如何构建页面布局和他们潜在的内容类型

  10. Android 开发最佳实践

    原文地址:https://github.com/futurice/android-best-practices/blob/master/translations/Chinese/README.cn.m ...