New features of Php5.5 Generators in ** PHP5.5.0 **, the generator * (Generators) * feature is added to simplify implementation of the Iterator interface * (Iterator) * complexity of creating a simple iterator.
Through the generator, we can easily use foreach to iterate a series of data without having to build the objects to be iterated in the memory in advance, greatly reducing the memory overhead.
When a generator function is called, it returns an iteratable object. when iteration is performed on this object, PHP will call the generator function as needed, in addition, when the generator generates a new value using the newly added keyword yield, it stores the internal status of the iterator. When the iterator does not have new values to be generated, the generator function can exit directly and the external function continues to be executed.
Note: The return value of the return statement cannot be used in generator functions. if the return value is used, a compiler error occurs. However, it is acceptable to use an empty return, which will terminate the iterator.
Generator functions are the same as normal functions. The only difference is that the yield keyword is used in the function. The yield statement can be said to be the core of the generator function. In short, yield is like a return statement. The difference is that after a return statement is returned, the function ends. After yield is returned, it only suspends the execution of the function and transfers it to the external function for further execution. The next time you call the generator function, the code inside the generator function will continue to be executed.
A simple example-the range function of the generator version
A simple example is to use the range returned value of the foreach iteration function. if range (0, 1000000) is called, it will consume more than MB of memory. If you use a generator, you may only need to consume 1 kB of memory.
$ End) {throw new RuntimeException ("the start value cannot be greater than the end value");} for ($ I = $ start; $ I <= $ end; $ I + = 1) {// use the yield keyword. every time the function returns $ I, the control is handed over to the external function to continue executing yield $ I ;}} foreach (xrange (1, 9) as $ number) {echo "$ number ";}
The output of the above example is as follows:
In the preceding example, a function named xrange is created. yield is used in the function to continuously generate the return value. when xrange (1, 9) is called, a generator object is created. We can modify the foreach line to print the xrange object.
...$xrange_res = xrange(1, 9);var_dump($xrange_res);foreach( $xrange_res as $number){...
Output
We can see that when xrange (1, 9) is executed, a Generator object is indeed returned.
Use the send method of the Generator object
In the preceding example, the yield statement is executed as a separate row, that is, the yield statement produces external results, in the iteration process, is there a way to obtain the value from outside the generator function?
There are always some methods. because a Generator object is returned after the Generator function is called, we can pass a value to the Generator function by calling the send method of this object. after calling the send method, yield receives the value sent by the send function.
" . $ret); $ret = (yield 'yield2'); var_dump("-->" . $ret);}$gen = gen();var_dump($gen->current());var_dump($gen->send('ret1'));var_dump($gen->send('ret2'));
Output:
Here we first create a generator object named gen, and then print the return value of the $ gen-> current () method. the returned value is the current value generated by the iterator during the first iteration, therefore, yield1 is output.
Next, we call the $ gen-> send ('ret ') method. in this case, the first yield statement in the generator returns the value ret1 passed by this method, therefore, the value of $ ret is output as ret1.
Then, because the generator executes the third statement $ ret = (yield 'yield2 '), the second external var_dump outputs yield2. The final call of $ gen-> send ('ret2') is similar to that of the first time. However, no yield is returned after the generator calls yield internally.
Note that the $ ret = (yield 'yield2 ') statement contains the yield 'yield2' statement, which is mandatory. if yield is used in the expression context, yield must be placed in brackets; otherwise, an error is reported.
Returns the joined array.
In the preceding example, we use the yield keyword to return a single value. In fact, PHP also supports returning an associated array. the basic syntax is as follows:
yield key => val
You can use this syntax format to return the same results as the traversal management array during foreach.
'mylxsw', 'site' => 'http://aicode.cc' ]; foreach ($array as $key => $val) { yield $key => $val; }}foreach(gen2() as $key => $val) { var_dump($key . ' : ' . $val);}
Output:
Use reference
We can also let the generator return data as a reference, so that the value of the internal data of the generator can be directly modified outside the generator.
0) { yield $value; }}foreach (gen_reference() as &$number) { echo (--$number).'... ';}
In the preceding example, you must note that & $ number is used for defining and traversing generator functions.
Finally, the generator and the custom iterator object are not exactly the same. Once the generator starts iteration, it cannot rewind any more. it can only iterate forward until the iteration is completed. If you want to iterate a generator object multiple times, you can call the generator function multiple times to create a new generator object or use the clone keyword.
Refer:
Cooperative multitasking using coroutines (in PHP !) Generators