深入剖析:生成器关键词yield表示每次生成一个值并返回,知道下一次迭代在生产下一个值;php在使用生成器的时候会返回一个Generator
类的对象,对该对象的每次迭代,Generator实例都会计算出下一次需要迭代的值,直到不再产生新值为止.
这个的作用就是,你不论迭代循环多少次,每次都只有一个值存放在内存中,从而提供性能.
在回过头来看thinkphp6
的**游标查询`,
$cursor = Db::table('user')->where('status', 1)->cursor();
foreach($cursor as $user){
echo $user['name'];
}
变量$cursor其实是一个Generator对象,对他每进行一次foreach,才会去获取一条用户数据$user,而不是一次性的将所有数据获取出来.
//普通函数
function xrange($num) {
$data = [];
for($i=0;$i<$num;$i++){
$data[] = time();
}
return $data;
}
$result = xrange(1000);
foreach($result as $val){
sleep(1);
echo $val.'<br/>';
}
这个普通的函数返回一个要求长度的时间内容数组,假设$num=100万
,那$data
数组就会是一个拥有100万的键值临时存放在内存中的数据,这回占用很大的内存空间,并占用处理时间.
//生成器方式
function xrange($num) {
for($i=0;$i<$num;$i++){
yield time(); //这里的关键词`yield`很重要,它返回一个生成器的对象实例.
}
}
这个代码同样进行如上的调用,发现结果是不一样的.我们来比较两次的实现过程.
有关生成器的高级应用-协程
在PHP中使用协程实现多任务调度