前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Understanding PHP Generators(译)Understanding PHP Generators

Understanding PHP Generators(译)Understanding PHP Generators

作者头像
zhuanxu
发布2018-08-23 12:50:16
3140
发布2018-08-23 12:50:16
举报
文章被收录于专栏:进击的程序猿进击的程序猿

PHP Generators

Understanding PHP Generators

为什么需要谈论Generators,作为互联网应有,更快的速度意味着更好的用户体验,而Generators则是php中解决速度和内存的杀手锏

原文

代码

What are PHP Generators?

在php5.5中加入,generators解决了在一个loop中不需要在内存中构建整个数组的问题,可能这么说还不是很明了

talk is cheap, show me the code

我们来看下一段代码,保存为文件generator.php

代码语言:javascript
复制
<?php

function getRange ($max = 10) {
    $array = [];

    for ($i = 1; $i < $max; $i++) {
        $array[] = $i;
    }

    return $array;
}

foreach (getRange(15) as $range) {
    echo "Dataset {$range} <br>";
}

我们可以通过命令快速启动以个server

代码语言:javascript
复制
php -S localhost:8000

如果我们访问http://localhost:8000/generator.php我们会看到下面

代码语言:javascript
复制
Dataset 1 
Dataset 2 
Dataset 3 
Dataset 4 
Dataset 5 
Dataset 6 
Dataset 7 
Dataset 8 
Dataset 9 
Dataset 10 
Dataset 11 
Dataset 12 
Dataset 13 
Dataset 14 

代码很容易理解,也没什么问题,但是如果我们改动下代码:

代码语言:javascript
复制
<?php

foreach (getRange(PHP_INT_MAX) as $range) {
    echo "Dataset {$range} <br>";
}

此时最大数变为了PHP_INT_MAX,再次运行就会出现下面的错误:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 134217736 bytes) in /private/tmp/php-generator/generator.php on line 7

超过最大内存了,此时一个可能的解决方案是修改php.ini 然后增加memory_limit。但是这个真能解决问题吗,我们是否真的希望一个脚本耗尽了我们的内存,显然是no!

Using Generators

我们还是实现同样的功能,这次我们创建一个generator函数

代码语言:javascript
复制
<?php

function getRange ($max = 10) {
    for ($i = 1; $i < $max; $i++) {
        yield $i;
    }
}

foreach (getRange(PHP_INT_MAX) as $range) {
    echo "Dataset {$range} <br>";
}

分析这次的getRange函数,这次我们只是在loop中yield值,yield类似于return,不同之处在于yield只有在被返回的值需要的时候才会产生这个值,不会让整个返回集合都在内存中

此时我们再次访问http://localhost:8000/generator.php,只要给浏览器足够的时间,所有的数据都会返回

Why Do This?

我们的目标是提升速度,但是内存不增加。很多时候,我们在处理log文件的时候,经常会遇到内存耗尽的情况,使用generator就能很好的解决

Returning Keys

除了返回简单的值,我们还能返回键值对

代码语言:javascript
复制
<?php

function getRange ($max = 10) {
    for ($i = 1; $i < $max; $i++) {
        $value = $i * mt_rand();

        yield $i => $value;
    }
}
foreach (getRange(PHP_INT_MAX) as $range => $value) {
    echo "Dataset {$range} has {$value} value<br>";
}

Sending Values to Generator

我们除了可以从generators中读数据,还能往里面写数据

代码语言:javascript
复制
<?php

function getRange ($max = 10) {
    for ($i = 1; $i < $max; $i++) {
        $injected = yield $i;

        if ($injected === 'stop') return;
    }
}
$generator = getRange(PHP_INT_MAX);

foreach ($generator as $range) {
    if ($range === 10000) {
        $generator->send('stop');
    }

    echo "Dataset {$range} <br>";
}

注意: 在generators中使用return,将会退出generator

Don't Misuse Generators

Generators用来高效使用内存,但是使用Generators并不意味着不会出现内存耗尽的情况,如果错误使用的话,也会遇到同样的问题。

Conclusion

Generators给我们提供了无法拒绝的性能提升。大多数时候,我们不需要高性能的服务器来解决问题,需要的这是我们重构下代码。Generators非常棒,我们应该多使用它。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016.10.27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Understanding PHP Generators
    • What are PHP Generators?
      • Using Generators
        • Why Do This?
          • Returning Keys
            • Sending Values to Generator
              • Don't Misuse Generators
                • Conclusion
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档