Press "Enter" to skip to content

PHP5.5或将引入Generators

最早的时候, 我记得是去年我刚加入开发组的时候, 神仙同学曾经提过, 问我是否可以考虑为PHP实现yield. 我当时做过尝试, 但是最后发现需要大改zend executor, 而当时的我还没有那么大的魄力(因为我记得当时我的第一个RFC刚刚被拒绝)认为我能说服那么多人接受这个变动, 所以后来就不了了之了.
但, 现在Nikita Popov, 完整的实现了这个RFC: Generators, 并且已经提供了一个可用的实现, 目前这个RFC在投票阶段, 投票形式也比较乐观, 所以如果不出大问题, PHP5.5将会引入这一新特性.
我就这里为大家简单介绍下, 这个新特性.
所谓Generators, 我们以下称为"生成器", 是一种可以返回迭代器的生成器. 呵呵, 这话有点绕, 让我们看看一个代码, 在没有迭代器之前, 如果我们遍历一个动态生成的数组:

<?php
   function return_array() {
       $array = dummy(); //计算全部数组内容
       return $array;
   }
  foreach (return_array() as $v) {
  }

这里就有一个问题, 我们需要一次性生成全部数组内容, 并且返回, 想象一下如果数据来源非常大, 我们无法一次性读入内存.
当然, 我们可以采用一个类, 封装一个支持迭代的实现:

<?php
  class dummy implements Iterator {
     public function rewind() {
       //实现代码
     }
    public function valid() {
       //实现代码
    }
    public function current() {
       //实现代码
    }
    public function key() {
       //实现代码
    }
    public function next() {
       //实现代码
    }
  }
  foreach (new Dummy() as $v) {
  }

相比这种实现, 生成器提供了一种更加简便的选择, 比如实现如上同样的功能:

<?php
function genrators() {
   while ($i = dummy_line()) //生成数组的一个元素
   {
          yield $i;
   }
}
foreach (generators() as $v) {
}

也就是说, 每当产生一个数组元素, 就通过yield关键字返回成一个, 并且函数执行暂停, 当返回的迭代器的next方法被调用的时候, 会恢复刚才函数的执行, 从上一次被yield暂停的位置开始继续执行, 到下一次遇到yield的时候, 再次返回.
好了, 这就是个简单的介绍, 如果大家有兴趣, 可以搜索一下其他已经实现了Generators语言的相关介绍.
呵呵, 大家觉得这个新特性怎么样呢?

24 Comments

  1. ルイヴィトンバッグ
    ルイヴィトンバッグ September 15, 2019

    スーパーコピー 時計 – スーパーコピー 時計
    ○各種のブランド偽物(コピー商品)の指輪.ネックレス
    ○各種のブランド偽物(コピー商品)のベルト
    ○各種のブランド偽物(コピー商品)のマフラー
    ○ スタイルが多い、品質がよい、価格が低い!
    ○ S品質 シリアル付きも有り 付属品完備!
    ○必ずご満足頂ける品質の商品のみ販売しております.
    ○ 品質を最大限本物と同等とする為に相応の材質にて製作している為です.
    人気の売れ筋商品を多数取り揃えております。
    全て激安特価でご提供.お願いします。
    ルイヴィトンバッグ https://www.cocoejp1.com

  2. 家居照明
    家居照明 April 28, 2018

    这个还是比较厉害的,越来越灵活

  3. 无敌WEB
    无敌WEB February 13, 2014

    今天才看到这个,失败啊,和python的yeild一样了,PHP越来越强大了

  4. baidu
    baidu June 5, 2013

    php作为常驻进程时候的可能内存泄露问题要是也没问题了就好了。。。

  5. baidu
    baidu June 5, 2013

    php 5.3已经支持多线程,见pecl的pthread扩展,真正的多线程支持。
    php5.5 支持基于Generators的协程(coroutines)
    越来越强大了。

  6. aureole
    aureole December 4, 2012

    不错
    不过在这里我有个疑惑
    yield当做PHP关键词来使用了
    如果数据量大的情况下逐条的暂停这样就非常频繁了
    不知是否来满足一下PHP的强大的习惯比如可以控制生成的数据量然后在”yield”一下,如此一来,特别是大数据量的时候效果就很明显咯。
    鸟哥,你怎么看

  7. jianwu
    jianwu October 19, 2012

    现在比较希望实现的是参数的类型检查。如
    function test(int $num,bool $add){
    if($add){
    return $num+$num;
    } else {
    return $num * $num;
    }
    }
    其实,php5就不应该向前兼容,而应该独立,现在页面里的php代码越来越多,越来越复杂,过程式的代码根本满足不了要求。所以php5就应该变成一种轻量式的java。

  8. ciogao
    ciogao September 28, 2012

    学习ing ^

  9. shafreeck
    shafreeck September 6, 2012

    有些Python 的味道了,可以基于Generator实现协程了

  10. francis
    francis September 3, 2012

    while ($i = dummy_line()) //生成数组的一个元素
    {
    yield $i;
    }
    只想说,这还是PHP么,好像第一次出现这样的语法……

  11. 刘悦
    刘悦 September 1, 2012

    鸟哥,这个特性是协程概念的一种实现么?

  12. assad
    assad August 31, 2012

    OO 的设计是一只混合 Perl 和 Java 的怪物.

  13. 重生
    重生 August 31, 2012

    这个特性感觉很不错呀,不知实际应用是否会有很多弊端

  14. Magic
    Magic August 31, 2012

    特性不错,但是如果我的数据来源是数据库,返回的数据量是上百万条(不能完全放到内存里面),yield能解决这个问题吗?

  15. Chon
    Chon August 31, 2012

    yield在C#等语言中很早就出现了, 但的确比Iterator好用多了.
    其实Iterator接口是有缺陷的.
    同一个iterator对象[1,2,3,4,5], 如果同时被两个嵌套的foreach运行就会出问题的.
    foreach($iterator as $i)
    {
    echo $i;
    foreach($iterator as $j)
    {
    echo $j;
    }
    }
    这个的运行结果是: 1,1,2,3,4,5
    不知道yield会不会有同样的问题呢? 这个要关注具体的实现呀.

  16. Cyrec
    Cyrec August 30, 2012

    和python的yield一样,不错不错,可企业中大部分还是PHP5.2,什么时候能普及到5.5啊

  17. larro
    larro August 30, 2012

    怎么说呢,特性越来越多,语言越来越灵活,也表示php越来越不简单了

  18. 86er
    86er August 30, 2012

    这个不错,期待。。。

Comments are closed.