目录

利用生成器,php也可以做到协程的效果。

迭代生成器概念原理

生成器提供了一种更容易的方法来实现简单的对象迭代,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低。

一个生成器被调用的时候,它返回一个可以被遍历的对象(迭代器)。当你遍历这个对象(迭代)的时候(例如通过一个foreach循环),PHP 将会在每次需要值的时候调用生成器函数,并在产生一个值之后保存生成器的状态,这样它就可以在需要产生下一个值的时候恢复调用状态。(目前看还是官方这段话解释最合适最容易理解,结合实际例子,再多看几遍。)

生成器允许你在 foreach 代码块中写代码来迭代一组数据而不需要在内存中创建一个数组, 那会使你的内存达到上限,或者会占据可观的处理时间。相反,你可以写一个生成器函数,就像一个普通的自定义函数一样, 和普通函数只返回一次不同的是, 生成器可以根据需要 yield 多次,以便生成需要迭代的值。

看一个简单例子(重写range函数):

function xrange($start, $limit, $step = 1) {
    for ($i = 0; $i < $limit; $i += $step) { 
        yield $i + 1 => $i;//yield除了可以生成简单值外,还可以生成键值对 key=>value
    }
}
foreach (xrange(0, 9) as $key => $val) {
    printf("%d %d \n", $key, $val);
}
// 输出
// 1 0
// 2 1
// 3 2
// 4 3
// 5 4
// 6 5
// 7 6
// 8 7
// 9 8

关键字yield

生成器函数的核心是yield关键字。它最简单的调用形式看起来像一个return申明,不同之处在于普通return会返回值并终止函数的执行,而yield会返回一个值给循环调用此生成器的代码并且只是暂停执行生成器函数。

注意:如果在一个表达式上下文(例如在一个赋值表达式的右侧)中使用yield,你必须使用圆括号把yield申明包围起来。 例如这样是有效的:

$data = (yield $value);
  • 生成器函数支持返回键值对

  • 生成器函数支持返回引用

yield from

function three(){
    yield 1;
    yield from two();
    yield from [3,4];
    
}
function two(){
    yield 2;
}

foreach(three() as $num){
    echo $num."\n";
}

send传递值

PHP协程实现 迭代器 & 生成器 - 9ong

通俗易懂PHP迭代生成器 - 9ong

参考

PHP协程实现 迭代器 & 生成器 - 9ong

通俗易懂PHP迭代生成器 - 9ong