0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

PHP中的生成器

汽车电子技术 来源:程序猿零壹 作者:程序猿零壹 2023-01-20 10:44 次阅读
你好, 我是程序猿零壹。******

******今天要给大家带来php中yield的用法。对于yield,我相信大部分的人依旧是不会用,甚至不知道什么是yield。那么今天这篇文章就是来告诉大家有关于yield的一些用法,以及如何用yield来解决我们在php中遇到的问题。希望对大家有所帮助。******

******不知道大家有没有碰到过这样的问题,使用excel导入大量数据的时候会失败,并且提示以下错误信息:******

Fatal Error: Allowed memory size of xxxxxx bytes

******这个是因为在php程序中,是将变量存储在内存中。当从excel中要导入的数据量过大的时候,会出现内存不足的错误提示。

要解决这个问题,可以通过修改php中对于最大运行内存的设置:

ini_set('memory_limit', '200M');

但是这么做不能从根本上解决问题,当我们需要读取5g甚至更大文件的时候,我们的运行内存可能就吃不消了。

幸好,在php5.5之后提新增了生成器(Generators)特性,用于简化实现迭代器接口(iterator)创建简单的迭代器的复杂性。通过生成器,我们可以轻松的使用 foreach 迭代一系列的数据,而不需要事先在内存中构建要被迭代的对象,大大减少了内存的开销。

这样说可能比较抽象,不易于理解。所以我们先抛开有关于生成器的概念,先来看一个简单的例子。

$arr = range(1,100)

这里用到了range函数,它的作用是在内存中生成一个数组包含每个在指定范围内的值,并返回该数组。

如果我们自己来实现这样一个数组,应该怎么做呢?我们来看下面的代码:

function xrange($start,$end,$step=1){  
  $data = [];  
  for($i=$start;$i<$end,$i += $step) {    
    $data[] = $i;  
  }  
  return $data;
}
$start = memory_get_usage();
$data = xrange(1,1000);
foreach ($data as $value) {    
  echo $value.PHP_EOL;
}
$end = memory_get_usage();
echo "start:".$start.PHP_EOL;
echo "end:".$end.PHP_EOL;
echo "used:".($end - $start);

我们来看下start为1,end 分别为 10,100,1000,10000的情况下的内存消耗情况分别是怎么样的:

xrange(1,10); // used = 3480 0.0033187866210938MB
xrange(1,100); // used = 30168 0.028770446777344MB
xrange(1,1000); // used = 285144 0.27193450927734MB
xrange(1,10000); // used = 2957784 2.8207626342773MB

不难看出,随着$end的增大,所占用的内存也越来越大。

接下来我们来改造下xrange函数:

function xrange($start,$end,$step=1){  
  for($i=$start;$i<$end,$i += $step) {    
    yield $i;  
  }
}

我们删除了数组data,并且也删除了返回值,而在foreach的循环体里,在i前面添加关键字:yield。****

我们来看下改造之后的内存消耗:

xrange(1,10); // used = 256 0.000244140625MB
xrange(1,100); // used = 256 0.000244140625MB
xrange(1,1000); // used = 256 0.000244140625MB
xrange(1,10000); // used = 256 0.000244140625MB

Wow,这个结果令人惊讶。我们奇迹的发现了,内存消耗并没有随着$end的增大而增大,甚至是完全一样。

我们来还原一下代码的执行过程:

******首先调用xrange函数,传参$end=10,但是for循环了一次然后停止了,并且告诉foreach第一次循环可以用的值。


  1. ******foreach开始对$data循环,并使用for给的一个值执行输出。******
    
  2. ******foreach开始第二次循环,它向for循环又请求了一次******
    
  3. ******for循环又执行了一次,并将新的值告诉foreach
    

  4. ******foreach拿到第二个值,开始输出。
    

******所以,整个代码执行中,始终只有一个记录值参与循环,内存中也只有一条信息。


无论开始传入按的$end有多大,由于不会立即生成所有结果集,所以内存始终是一条循环的值,也就不会占用太大的内存了。

******看到这里,你是不是想说,“就这?”。生成器的用处当然不止这一些,还有其他的用武之地,比如协程。只不过因为本人才疏学浅,只能跟大家分享这么多了。大家感兴趣的话,可以看下鸟哥关于在php中使用协程实现多任务调度的文章。

好了,今天就到这里,如果大家觉得有用的话,不要忘记点赞收藏哦~

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 程序
    +关注

    关注

    115

    文章

    3753

    浏览量

    80709
  • 生成器
    +关注

    关注

    7

    文章

    313

    浏览量

    20933
  • PHP
    PHP
    +关注

    关注

    0

    文章

    452

    浏览量

    26623
收藏 人收藏

    评论

    相关推荐

    如何去使用生成器

    生成器的工作原理是什么?如何去使用生成器呢?
    发表于 10-25 08:44

    python生成器

    了在大量数据下内存消耗过猛的问题。当你在 Python Shell 敲入一个生成器对象,会直接输出 generator object 提示你这是一个生成器对象>>> gen
    发表于 02-24 15:56

    pim卡资料生成器

    pim卡资料生成器
    发表于 11-22 23:23 6次下载

    汉语句子联想生成器

    在一定的语言环境汉语词语之间存在着优先组合搭配关系,据此,在本文中利用互信息、数理统计和人脑联想记忆的相关理论,设计了一个汉语句子联想生成器,使用该生成器
    发表于 09-26 14:25 20次下载

    自制酸奶生成器

    自制酸奶生成器
    发表于 04-23 11:48 924次阅读
    自制酸奶<b class='flag-5'>生成器</b>

    LED段码生成器

    本文提供的LED段码生成器,希望对你的学习有所帮助!
    发表于 06-03 15:19 97次下载

    代码生成器的应用

    jeesite框架代码生成器,可以很方便的生成代码,挺不错的。
    发表于 01-14 15:19 0次下载

    数码管代码生成器

    数码管代码生成器,迅速生成数码管的相应代码
    发表于 04-25 10:54 40次下载

    STM32库函数代码自动生成器正式版

    STM32库函数代码自动生成器正式版 STM32库函数代码自动生成器正式版
    发表于 07-25 18:52 0次下载

    AN-113:精密坡道生成器

    AN-113:精密坡道生成器
    发表于 05-16 12:04 6次下载
    AN-113:精密坡道<b class='flag-5'>生成器</b>

    python生成器是什么

    计算,从而缓解了在大量数据下内存消耗过猛的问题。 当你在 Python Shell 敲入一个生成器对象,会直接输出 generator object 提示你这是一个生成器对象 gen = (i for i
    的头像 发表于 02-24 15:53 3567次阅读

    Arduino赞美生成器

    电子发烧友网站提供《Arduino赞美生成器.zip》资料免费下载
    发表于 11-09 14:22 1次下载
    Arduino赞美<b class='flag-5'>生成器</b>

    通用RFID生成器

    通用RFID生成器资料分享
    发表于 02-10 15:35 1次下载

    【虹科】为什么需要网络流量生成器

    什么是网络流量生成器,为什么我需要一个?网络流量生成器是一种将流量馈送到网络以测试和优化网络设备、协议和拓扑性能的工具。使用流量生成器,可以选择要在实验室测试的特定流量类型。通过控制
    的头像 发表于 03-11 10:09 1022次阅读
    【虹科】为什么需要网络流量<b class='flag-5'>生成器</b>?

    TSMaster报文发送的信号生成器操作说明

    信号生成器功能是TSMaster分析的报文发送模块。信号生成器用于发送和配置每个CAN/LIN信号的值变化行为,简而言之,这是一个可以控制和调整CAN/LIN信号值的功能。我们可选择的信号
    的头像 发表于 12-23 08:21 880次阅读
    TSMaster报文发送的信号<b class='flag-5'>生成器</b>操作说明