Php5.5 new Features generators detailed

Source: Internet
Author: User

In the **php5.5.0** version, a new generator * (generators) * feature was added to simplify the complexity of implementing an Iterator interface * (Iterator) * To create a simple iterator.

With the generator, we can easily iterate through a foreach series of data without having to build the objects in memory to be iterated in advance, greatly reducing the memory overhead.

When the generator function is called, it returns an iterative object, and when the object is iterated, PHP will call the generator function when it is needed and save the state inside the iterator when the generator uses the new keyword to yield produce a fresh value. When the iterator does not have a new value to generate, the generator function can exit directly and the external function continues execution.

Note that in a generator function, you cannot use the return return value of a statement, and return a compiler error occurs when you use the return value. However, return it is possible to use NULL, which causes the iterator to terminate.

The generator function is the same as the normal function, and the only difference is that the keyword is used within the function yield . The yield statement can be said to be the core of the generator function, simply, yield just like the return statement, the difference is that the return function ends after the statement returns, and the use yield of return, just pause the execution of the function, go to the external function to continue execution, the next time you call the generator function , continue executing the code inside the generator function.

A simple example-the range function of the generator version

A simple example is the use foreach of the return value of an iterative function range , which, if invoked range(0, 1000000) , consumes more than 100M of memory. Using the generator, you may only need to consume 1KB of memory.

<?phpfunction xrange($start, $end) {    if ($start > $end) {        throw new RuntimeException("起始值不能大于截止值");    }    for ($i = $start; $i <= $end; $i += 1) {        // 使用yield关键字,每次到这里函数都会返回$i的值,并且控制权交给外部函数继续执行        yield $i;    }}foreach (xrange(1, 9) as $number) {    echo "$number ";}

The above example output is as follows:

In the example above, we have created a xrange function called, which uses the yield constant generation of return values, and the call xrange(1, 9) creates a generator object. We can modify foreach this line to print out the xrange object to see

...$xrange_res = xrange(1, 9);var_dump($xrange_res);foreach( $xrange_res as $number){...

Output

As you can see, it xrange(1, 9) is true that an object was returned when executed Generator .

Use the Send method of the Generator object

In the example above, we used the yield statement as a separate line of statements, that is, the yield statement produces the result to the outside, then there is no way in the iterative process from the outside of the generator function to get the value?

There is always a way to do this, because the call to the generator function returns an Generator object, so we can send pass a value to the generator function externally by calling the method of the object, and after the method is called send , the yield send value sent by the function is received.

<?phpfunction gen() {    $ret = (yield ‘yield1‘);    var_dump("-->" . $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 gen generator object named, and then we print the $gen->current() return value of the method, which is the current value produced by the first iteration of the iterator, so it is output yield1 .

Then we call the method, and the $gen->send(‘ret‘) first statement inside the generator yield returns the value passed by the method ret1 , so the output $ret value is ret1 .

The $ret = (yield ‘yield2‘) second output of the external is then due to the third statement being executed inside the generator var_dump yield2 . The last call $gen->send(‘ret2‘) is similar to the first, but this time the generator is not inside the call and yield yield is returned NULL .

Note that in the statement here, the $ret = (yield ‘yield2‘) parentheses are used to include the yield ‘yield2‘ statement, which is required, and if used in the context of an expression, it must be enclosed yield yield in parentheses, otherwise an error will be made.

Returns an associative array

In the previous example, we used the yield keyword to return always a single value, in fact PHP also provides support for returning an associative array, the basic syntax:

yield key => val

Use this syntax format to return the same results as the traversal management array when foreach is used.

<?phpfunction gen2() {    $array = [        ‘username‘ => ‘mylxsw‘,        ‘site‘     => ‘http://aicode.cc‘    ];    foreach ($array as $key => $val) {        yield $key => $val;    }}foreach(gen2() as $key => $val) {    var_dump($key . ‘   :   ‘ . $val);}

Output:

Using references

We can also have the generator return data as a reference, so that the values of the generator's internal data can be modified directly outside the generator.

<?phpfunction &gen_reference() {    $value = 3;    while ($value > 0) {        yield $value;    }}foreach (gen_reference() as &$number) {    echo (--$number).‘... ‘;}

In the above example, it is important to note that the definition and traversal of the generator function is used &$number .

Finally, the generator is not exactly the same as the custom iterator object, and once the generator starts iterating, it can no longer be rewind iterated until the iteration is complete. If you want to iterate over a generator object multiple times, you can call the generator function multiple times to create a new generator object or use the Clone keyword.

Reference:

    • Cooperative multitasking using coroutines (in php!)
    • Generators

Php5.5 new Features generators detailed

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.