网站首页 > 技术教程 正文
文章内容
1、概述
生成器是 PHP 5.5 引入的新特性,但是目测很少人用到它,其实这是个非常有用的功能。
生成器和迭代器有点类似,但是与标准的PHP迭代器不同,PHP生成器不要求类实现Iterator接口,从而减轻了类的开销和负担。生成器会根据需求每次计算并产出需要迭代的值,这对应用的性能有很大的影响:试想假如标准的PHP迭代器经常在内存中执行迭代操作,这要预先计算出数据集,性能低下;如果要使用特定方式计算大量数据,如操作Excel表数据,对性能影响更甚。此时我们可以使用生成器,即时计算并产出后续值,不占用宝贵的内存空间。
2、创建生成器
生成器的创建方式很简单,因为生成器就是PHP函数,只不过要在函数中一次或多次使用yield关键字。与普通的PHP函数不同的是,生成器从不返回值,只产出值。下面是一个简单的生成器实现:
function getLaravelAcademy() { yield 'http://LaravelAcademy.org'; yield 'Laravel学院'; yield 'Laravel Academy'; }
很简单吧!调用此生成器函数时,PHP会返回一个属于Generator类的对象,这个对象可以使用foreach函数迭代,每次迭代,PHP会要求Generator实例计算并提供下一个要迭代的值。生成器的优雅体现在每次产出一个值之后,生成器的内部状态都会停顿;向生成器请求下一个值时,内部状态又会恢复。生成器内部的状态会一直在停顿和恢复之间切换,直到抵达函数定义体的末尾或遇到空的return语句为止。我们可以使用下面的代码调用并迭代上面定义的生成器:
foreach(getLaravelAcademy() as $yieldedValue) { echo $yieldedValue, PHP_EOL; }
上面代码输出如下:
http://LaravelAcademy.org Laravel学院 Laravel Academy
3、使用生成器
下面我们实现一个简单的函数用于生成一个范围内的数值,以此说明生成器是如何节省内存的。首先我们通过迭代器来实现:
function makeRange($length) { $dataSet = []; for ($i=0; $i<$length; $i++) { $dataSet[] = $i; } return $dataSet; } $customRange = makeRange(1000000); foreach ($customRange as $i) { echo $i . PHP_EOL; }
此时执行会报错,提示超出单个PHP进程内存限制(要为100万个数字提供内存空间):
下面我们来改进实现方案,使用生成器实现如下:
function makeRange($length) { for ($i=0; $i<$length; $i++) { yield $i; } } foreach (makeRange(1000000) as $i) { echo $i . PHP_EOL; }
再次执行就可以毫无压力的打印出结果,因为生成器每次只需要为一个整数分配内存。
此外,一个常用的使用案例就是使用生成器迭代流资源(文件、音频等)。假设我们想要迭代一个大小为4GB的CSV文件,而虚拟私有服务器(VPS)只允许PHP使用1GB内存,因此不能把整个文件都加载到内存中,下面的代码展示了如何使用生成器完成这种操作:
function getRows($file) { $handle = fopen($file, 'rb'); if ($handle == FALSE) { throw new Exception(); } while (feof($handle) === FALSE) { yield fgetcsv($handle); } fclose($handle); } foreach ($getRows($file) as $row) { print_r($row); }
上述示例一次只会为CSV文件中的一行分配内存,而不会把整个4GB的CSV文件都读取到内存中。
4、总结
生成器是功能多样性和简洁性之间的折中方案,生成器只是向前进的迭代器,这意味着不能使用生成器在数据集中执行后退、快进或查找操作,只能让生成器计算并产出下一个值。迭代大型数据集或数列时最适合使用生成器,因为这样占用的系统内存最少。生成器也能完成迭代器能完成的简单任务,而且使用的代码更少。
总而言之,生成器并没有为PHP添加新功能,不过使用生成器大大简化了某些任务
- 上一篇: 新手搭建博客网站(新手搭建博客网站怎么弄)
- 下一篇: OA办公系统之流程审批,打破空间限制(二)
猜你喜欢
- 2024-10-21 常见面试问题之-设计模式 重要包含PHP代码实现额,PHP开发者必看
- 2024-10-21 php生命周期介绍(php的生命周期, 启动流程, 多看tipi)
- 2024-10-21 Laravel框架命名空间的定义(laravel框架关键技术解析)
- 2024-10-21 网站建站流程-空间购买(网站空间商选择考虑三大因素)
- 2024-10-21 准确JavaScript世界观:复杂值vs原始值&&内存空间(1)
- 2024-10-21 如何搭建个人博客网站?角点科技教你搭建博客网站
- 2024-10-21 建设属于自己的网站需要什么(建设属于自己的网站需要什么资质)
- 2024-10-21 省钱了!使用极空间搭建一个免费的MariaDB数据库并实现远程访问
- 2024-10-21 Windows+Apache+MySQL+PHP4 官方推荐详细安装步骤
- 2024-10-21 PHP内存管理机制与垃圾回收机制(php 内存模型)
你 发表评论:
欢迎- 最近发表
-
- Win11学院:如何在Windows 11上使用WSL安装Ubuntu
- linux移植(Linux移植freemodbus)
- 独家解读:Win10预览版9879为何无法识别硬盘
- 基于Linux系统的本地Yum源搭建与配置(ISO方式、RPM方式)
- Docker镜像瘦身(docker 减小镜像大小)
- 在linux上安装ollama(linux安装locale)
- 渗透测试系统Kali推出Docker镜像(kali linux渗透测试技术详解pdf)
- Linux环境中部署Harbor私有镜像仓库
- linux之间传文件命令之Rsync傻瓜式教程
- 解决ollama在linux中安装或升级时,通过国内镜像缩短安装时长
- 标签列表
-
- 下划线是什么 (87)
- 精美网站 (58)
- qq登录界面 (90)
- nginx 命令 (82)
- nginx .http (73)
- nginx lua (70)
- nginx 重定向 (68)
- Nginx超时 (65)
- nginx 监控 (57)
- odbc (59)
- rar密码破解工具 (62)
- annotation (71)
- 红黑树 (57)
- 智力题 (62)
- php空间申请 (61)
- 按键精灵 注册码 (69)
- 软件测试报告 (59)
- ntcreatefile (64)
- 闪动文字 (56)
- guid (66)
- abap (63)
- mpeg 2 (65)
- column (63)
- dreamweaver教程 (57)
- excel行列转换 (56)
本文暂时没有评论,来添加一个吧(●'◡'●)