1、迭代生成器
生成器的核心是一个yield关键字,一个生成器函数看起来像一个普通的函数,不同的是:普通函数返回一个值,而一个生成器可以yield生成许多它所需要的值。生成器函数被调用时,返回的是一个可以被遍历的对象。
yield和return有点类似,不过不同的是,return会返回值并且终止代码的执行,而yield会返回一个值给循环调用此生成器的代码并且只是暂停执行生成器函数。

function gen_one_tow_three(){
for($i = 1; $i <=3; $i++){
//注意:变量$i的值在不同的yield之间是保持传递的。
yield $i;
}
}
$generator = gen_one_tow_three();
var_dump($generator);
echo "<br>";
var_dump($generator instanceof Iterator);
echo "<br>";
foreach($generator as $value){
echo $value."\n";
}

输出:
object(Generator)#1 (0) { }
bool(true)
1 2 3
调用gen_one_tow_three()的时候,里面的代码并没有真正的执行,而是返回一个生成器对象$generator = Generator Object(),$generator instanceof Interator说明Generator事项了Iterator接口,可以用foreach进行遍历,每次遍历都会隐式调用current()、next()、key()、valid()等方法。(Generator类中的方法)
2、处理大数据
下面通过实现一个xrange函数来简单说明:

function xrange($start,$end,$step = 1){
for ($i=$start; $i <=$end; $i+=$step) {
yield $i;
}
} foreach(xrange(1,1000000) as $num){
echo $num,"\n";
}

上面这个xrange()函数提供了和php的内建函数range()一样的功能,但不同的是range()函数返回的是一个包含值从1到100w的数组,而xrange()函数返回的是依次输出这些值得一个迭代器,而不会真正以数组形式返回。
这种方法的优点是显而易见的,它可以让你在处理大数据集合的时候不用一次性的加载到内存中。甚至你可以处理无限大的数据流
3、处理大文件
在PHP读取大文件的时候,经常会出现内存不足的情况,如果文件过大的话,没法一次读取玩,采用yield来实现大文件的读取。
3.1)老式读取

function readLocalFile($fileName){
$handle = fopen($fileName,'r');
$lines = [];
while(!feof($handle)){
$lines[] = fgets($handle);
}
fclose($handle);
return $lines;
}

3.2)yield读取方式

function readYieldFile($fileName){
$handle = fopen($fileName,'r');
while(!feof($handle)){
yield fgets($handle);
}
fclose($handle);
}

//为了便于测试,写一个读取内存的辅助函数

function formatBytes($bytes){
if($bytes<1024){
return $bytes . "b";
}else if($bytes <1048576){
return round($bytes / 1024,2) ."kb";
}
return round($bytes / 1048576,2) . "mb";
}
//第一种,all.zip是一个158M的压缩文件
readLocalFile('./all.zip');
echo formatBytes(memory_get_peak_usage());

报错:Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 123 bytes) in

//第二种
$lines = readYieldFile('./all.zip');
foreach($lines as $row){}
echo formatBytes(memory_get_peak_usage());

输出:141.3kb

总结:
使用老式读取,返回的是一个包含每行数据的数组,而yield方式则返回的事宜个迭代器,而不会以真正的数组返回。
这种方法的有点可以让你在处理大数据集合的时候不用一次性的加载到内存中,甚至可以处理无限大的数据流。

PHP迭代生成器---yield的更多相关文章

  1. python3使用迭代生成器yield减少内存占用

    技术背景 在python编码中for循环处理任务时,会将所有的待遍历参量加载到内存中.其实这本没有必要,因为这些参量很有可能是一次性使用的,甚至很多场景下这些参量是不需要同时存储在内存中的,这时候就会 ...

  2. 简单了解一下php的迭代生成器yield

    yield是从PHP5.5开始有的,关于yidle的说明鸟哥的博客做了详细说明,我觉得是有点复杂,在看了几篇其他的帖子还有案例,我大概知道yield的作用就是在做大量数据循环处理的时候,能节省很大一部 ...

  3. Python生成器 yield

    迭代器与list相比较,就for in句型循环拿数据而言: 用list写很简洁,但如果list数据过大,会很消耗资源. 用iteration 迭代器写,则不会消耗那么多资源.他会随用随取,用一个拿一个 ...

  4. Python入门之迭代器/生成器/yield的表达方式/面向过程编程

    本章内容 迭代器 面向过程编程 一.什么是迭代 二.什么是迭代器 三.迭代器演示和举例 四.生成器yield基础 五.生成器yield的表达式形式 六.面向过程编程 ================= ...

  5. PHP性能优化利器:生成器 yield理解

    如果是做Python或者其他语言的小伙伴,对于生成器应该不陌生.但很多PHP开发者或许都不知道生成器这个功能,可能是因为生成器是PHP 5.5.0才引入的功能,也可以是生成器作用不是很明显.但是,生成 ...

  6. [PY3]——函数——生成器(yield关键字)

    函数—生成器篇 1. 认识和区分可迭代or生成器 1.1 可迭代对象 当你建立了一个列表,你可以逐项地读取这个列表,这叫做一个可迭代对象 当你使用一个列表生成式来建立一个列表的时候,就建立了一个可迭代 ...

  7. 6 生成器 yield 协程

    1.生成器 ----> 1 b = [x*2 for x in range(100000000000)] MemoryError: 想生成一个存放很多数据的列表,但是又不想内存占用太多 每次用一 ...

  8. day4 内置函数 迭代器&生成器 yield总结 三元运算 闭包

    内置函数: 内置函数 # abs()返回一个数字的绝对值.如果给出复数,返回值就是该复数的模. b = -100 print(b) print(abs(b)) # all() 所有为真才为真,只要有一 ...

  9. php生成器yield

    上次说了php的生成器Iterator,这次说一下yield 迭代生成器 (迭代)生成器也是一个函数,不同的是这个函数的返回值是依次返回, 而不是只返回一个单独的值.或者,换句话说,生成器使你能更方便 ...

随机推荐

  1. Spring tools

    sts是什么? sts是spring tool suite的缩写,是基于eclipse的.开发spring应用的定制的开发环境. 提供了什么? 实现.调试.运行.部署spring应用的现成的环境.包括 ...

  2. mac使用vnc远程登录ubuntu16.04桌面

    mac使用vnc远程登录ubuntu16.04桌面 1.安装在Ubuntu上安装x11vnc,如下: sudo apt-get install x11vnc 2.配置vnc密码 x11vnc -sto ...

  3. git 比较两个分支不同的commit

    比如我们有 2 个分支:master, dev,现在想查看这两个 branch 的区别,有以下几种方式: undefined 1.查看 dev 有,而 master 中没有的: 1.查看 dev 有, ...

  4. WebService(axis2),整合springmvc

    webservice:不同组织或者部门之间互通数据 https://www.cnblogs.com/buggou/p/8183738.html 1 package com.sh.test; 2 3 4 ...

  5. javaScript(拼写树形)+ajax请求,去后台查找数据

    第一步:页面加载完成时,利用jquery中的一函数,调用js方法,js方法,发送ajax请求,去后台查找父类权限集合,响应回来json格式的数据,对数据进行操作,往页面上添加内容 //页面初始化加载菜 ...

  6. Vuex 通俗版教程告诉你Vuex怎么用

    写在文前: 最近一直在用vue开发项目,写来写去就是那么些方法,对于简单的项目一些常用的vue方法足以解决,但是涉及到页面状态,权限判断等一些复杂的传值,vuex是必须的.对于vuex也运用一段时间, ...

  7. VS中卸载Visual Assist X

    Tools=>Extensions and updates=>找到Visual Assist X 卸载:

  8. 算法习题---4-3黑白棋(UVa220)

    一:题目 系统提示当前旗手W/B(白/黑)下子,例如W下子,那么W下的位置必须是夹住黑色棋子的位置才可以. 夹住方式:横向.竖向.斜向 注意落子后将夹住的黑棋吞噬变为白棋 (一)题目详解 .棋盘以数组 ...

  9. php上传超大文件

    1.使用PHP的创始人 Rasmus Lerdorf 写的APC扩展模块来实现(http://pecl.php.net/package/apc) APC实现方法: 安装APC,参照官方文档安装,可以使 ...

  10. python中os.popen, os.system()区别

    直接上个例子吧,注意结果,os.system的结果只是命令执行结果的返回值,执行成功为0: >>> a=os.system('ls') Applications Movies pyt ...