Press "Enter" to skip to content

PHP 5.5 May Introduce Generators

Going back to the very beginning — I remember it was around the time I'd just joined the dev group last year, when a senior developer (神仙同学) raised the idea and asked whether I'd consider implementing yield for PHP. I did try it at the time, but I ultimately found it would require major changes to the Zend executor, and back then I didn't have that kind of conviction (I remember my first RFC had just been rejected at the time) that I could persuade that many people to accept such a change, so it fizzled out.
But now, Nikita Popov has fully implemented this RFC: Generators, and has already provided a working implementation. The RFC is currently in the voting stage, and the voting looks fairly optimistic, so barring any major issues, PHP 5.5 is set to introduce this new feature.
Let me give everyone a brief introduction to this new feature here.
So-called "generators" (hereafter just "generators") are a function that can return an iterator. Hehe, that's a bit of a mouthful. Let's look at a piece of code. Before iterators, if we wanted to iterate over a dynamically generated array:

<?php
   function return_array() {
       $array = dummy(); //compute the entire array content
       return $array;
   }
  foreach (return_array() as $v) {
  }

Here's the problem: we need to generate the entire array content at once, and then return it. Imagine if the data source is very large and we can't load it all into memory at once.
Of course, we could use a class that encapsulates an iterable implementation:

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

Compared with that kind of implementation, generators offer a much more convenient option, for instance to achieve the same functionality as above:

<?php
function genrators() {
   while ($i = dummy_line()) //generate one element of the array
   {
          yield $i;
   }
}
foreach (generators() as $v) {
}

In other words, each time an array element is produced, it's returned via the yield keyword, and the function's execution is suspended. When the next() method of the returned iterator is called, it resumes the function from where it was last suspended by yield, and keeps executing until it hits the next yield, at which point it returns again.
Alright, that's the simple introduction. If anyone's interested, you can search for introductions to other languages that have already implemented Generators.
Hehe, what do everyone think of this new feature?

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.