前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《PHP技术大全·第1卷》Generator 通俗解读

《PHP技术大全·第1卷》Generator 通俗解读

作者头像
猿哥
发布2019-07-25 23:05:22
5180
发布2019-07-25 23:05:22
举报
文章被收录于专栏:Web技术布道师Web技术布道师

PHP技术大全·第1卷(又名:你可能不知道的 PHP)

Generator (译作:生成器)通俗解读

  • PHP 版本要求 >PHP5.5.0,PHP7
  • Generator 的作用 提供了一种简单的方式实现 Iterator (译作:迭代器),从这里可以见得为啥 generator 函数能够直接使用 foreach 去遍历的原因啦,用于减少资源消耗(这里的资源主要是指计算机 RAM 内存)而不必实现复杂度更高的 Iterator 接口。说明一下,在 PHP 中只要实现了 Iterator 接口,因为 Iterator 接口继承了 Traversable (可遍历)接口, 因此相应的类实例(对象)便可以通过 foreach 去遍历(遍历就是指全部元素挨个过一遍),但你还想问笔者为啥继承了 Traversable 接口就能使用 foreach 去遍历,笔者的回答是请去看 PHP的 c 源码吧,地址是https://github.com/php/php-src,显然已经超出了本文的范畴,不过读者朋友大可以读读,开阔一下视野,到时顺便跟笔者分享一下源码的阅读心得。

下面是 Iterator 接口的伪代码(伪代码是指非真实代码,通常用于表达基本的用途)。

代码语言:javascript
复制
<?phpIterator extends Traversable {/* Methods */abstract public mixed current ( void )abstract public scalar key ( void )abstract public void next ( void )abstract public void rewind ( void )abstract public bool valid ( void )}?>
  • Generator 语法(所谓语法即编程语言官方规定的用法,不按规矩办事肯定不行啦)
  • Generator 的实例 在内存只有 1G 的 CentOS 云服务器上实现一个读取 2GB 文本日志文件逐行处理

1.1 错误的姿势

代码语言:javascript
复制
<?php    $fileContent = file_get_contents("/path/to/targetFile.log");//1G 内存无法装载 2GB 文本文件,直接报错       //报错类似:Fatal error: Allowed memory size of 25165824 bytes exhausted (tried to allocate 150 bytes) in [Blog root path]/wp-includes/pomo/mo.php on line 206    //...?>

1.2 正确的姿势

代码语言:javascript
复制
<?php   function readLines(){  $fileHandler = fopen("/path/to/targetFile.log","r");//第二个参数r即read,对文件 /path/to/targetFile.log 以只读的方式打开  //这里为啥叫 $fileHandler呢?handler译作:句柄在 PHP 中通常是指 Resource (译作:资源类型)的操纵杆,玩过魂斗罗,超级玛丽等手柄游戏的同学都知道,手柄就是游戏的操作装置。句柄也类似,是操作系统对资源(这里指的是文件资源)暴露出来的可操作选项的控制器。    try {        while ($line = fgets($fileHandler)) {//fgets 是读取文件的一行,并使文件指针指向下一行            yield $line;//yield 译作:产出,生成,可以这么理解:你一个生成器吧,好歹得产出个东西吧,跟 return 类似,它俩都是用来返回值的,但是 yield 是 generator 函数的搭档,能够 yeild (产出)多个值,有这个关键词之后 readLines 函数就变成了 generator 函数,接着才可以使用下面的 foreach 去遍历        }    } finally {        fclose($fileHandler);//这里切记一定要关闭文件句柄,若不关闭的话,它会占用操作系统资源,导致资源泄露(常见的主要是 memory leak,又叫内存泄露,就是指内存长时间被占用着无法再短时间内再利用)    }}foreach (readLines() as $n => $line) {    //下面就可以愉快的对 2G 大日志文件可以逐行处理了    doSomethingYouCan();}?>  
  • 最佳实践
  1. 巧用生成器可以帮助你在实际生产环境中写出性能比别人高而且更加节省内存资源的代码,当然它也是 PHPer 初中级别水平的一个分水岭。
  • 参考资料

  1. 生成器语法:http://php.net/manual/en/language.generators.syntax.php
  2. Iterator 接口:http://php.net/manual/en/class.iterator.php
  3. 生成器概览:http://php.net/manual/en/language.generators.overview.php

永久更新地址:https://gitee.com/nodestudy/phpgod/blob/master/zh/02.5.md

加Q群畅聊:374155314

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-04-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PHP技术大全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • PHP技术大全·第1卷(又名:你可能不知道的 PHP)
  • Generator (译作:生成器)通俗解读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档