• php yield使用


    一,概念
    1. yield简单的调用形式看起来像一个return申明,不同之处在于普通return会返回值并终止函数的执行,而yield会返回一个值给循环调用此生成器的代码并且只是暂停执行生成器函数。yield只有在调用的时候才会执行,并不产生多余的值,比如读取一个很大的文件或者计算大量的数据时,如果直接读取很有可能内存就爆了,而yield就可以做到把数据一行行读取到php运行内存,并非一次性读取到php运行内存,这样在运行时就会节省大量的内存;还有在遍历数据库的所有记录的时候,这个记录可能会很大,例如100万行,那么通过传统的办法就行不通了,首先通过web访问,php有超时时间,默认是30秒,那么就只能通过php cli的方式来执行,这样就没有超时时间了,但由于数据量太大,php循环时需要将数据全部载入内存中执行,由于数据量太大,php会报Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes)的错误,php默认的内存限制为128M,虽然可以通过修改php.ini中memory_limit的选项的值来提高内存限制,但始终不是最优的解决办法,这时通过生成器函数就可以极大节省内存开销。

    2. 另一方面,PHP早就实现了协程,yield关键字就是允许你从一个函数中让出执行权,需要的时候能重新回到让出的位置继续往下执行,但它没有流行起来也有多种原因,一个是它的传染性,每一层调用都需要加关键字,另一个就是PHP没有高效可靠的异步IO支持,让其食之无味。

    二,代码示例
    function createRange($num){
    	$data=[];
    	for($i=0;$i<$num;$i++){
    		$data[]=time();
    	}
    	return $data;
    }
    
    $res=createRange(10);
    foreach($res as $key=>$value){
    	sleep(1);
    	echo $value."
    "
    ; }

    运行结果为
    在这里插入图片描述
    使用yield 创建一个生成器

    function createRange($num){
    	for($i=0;$i<$num;$i++){
    		yield time();
    	}
    }
    $res=createRange(10);
    foreach($res as $key=>$value){
    	sleep(1);
    	echo $value."
    "
    ; }

    运行结果如下
    在这里插入图片描述
    未使用生成器的时候,createRange 很快生成一个 10个元素的数组$data,并立即返回,所以foreach 的是一个固定的数组。使用生成器后,createRange 不是一次性生成10元素,而是在foreach 中调用他的时候,他生成一个元素返回,并暂停。就是 foreach一次,for一次。

  • 相关阅读:
    微信小程序新版隐私协议弹窗实现最新版
    争议不断的AI绘画,靠什么成为了顶流?
    线程同步互斥锁
    C++11 条件变量
    HashMap的几种遍历方式及循环删除
    美国多ip站群vps的五大优势
    【附源码】Python计算机毕业设计木几画室管理系统
    服务器文件操作 ChannelSftp 的用法
    读完 RocketMQ 源码,我学会了如何优雅的创建线程
    如何对走势图进行画线分析
  • 原文地址:https://blog.csdn.net/sang521jia/article/details/139605766