当你需要处理一个5G的文件里面的数据时,你会怎么做,将文件里面的内容全部读取到一个数组里面去? 显然这种做法对小文件是没有问题的,但是对于大文件还是不行的
这时就需要用到 yield 了 ,注意这是php5.5之后才有的
1.首先我们看一个基本的代码
<?php
function aa($number){
for($i=0;$i<$number;$i++){
$data[] = $i.'-'.time();
}
return $data;
}
$result = aa(5);
foreach($result as $value){
sleep(1);//这里停顿1秒
echo $value.'<br />';
}
这是一个正常的代码,我们将传入的数据当做一个很大的数据(虽然目前是5),结果为
0-1555485328 1-1555485328 2-1555485328 3-1555485328 4-1555485328
(1)很明显,我们执行的循序是,先将for里面的全部执行完(因为时间戳都是一样的),然后再执行foreach这个函数。5条是没有问题的,但是如果是五百万条呢,会不会太大,占用太多资源
2.我们再看优化之后的
<?php function aa($number){ for($i=0;$i<$number;$i++){ yield $i.'-'.time(); } } $result = aa(5); foreach($result as $value){ sleep(1);//这里停顿1秒 echo $value.'<br />'; }
利用yield 返回数据,我们再看一下结果
0-1555485647 1-1555485648 2-1555485649 3-1555485650 4-1555485651
(2)我们可以发现,程序会先从for里面拿出一个值,然后利用这个值来进行foreach,当这次循环完了后,再自动去for里面取第二个值。可以发现,只是时间变了,结果内容完全是一样的
像这样一个值一个值的处理,不管你数据有多大,我始终只处理一个值。就很大程度上优化了代码 ,节约了资源
我们来运行一个实例,读取一个txt文件
<?php function read($path){ $file = fopen($path, "r"); //输出文本中所有的行,直到文件结束为止。 while(! feof($file)) { yield fgets($file)."<br>";//fgets()函数从文件指针中读取一行 } fclose($file); } $a = read('test.txt'); foreach ($a as $val){ echo $val; }
输出:
第1行
第2行
第3行
第4行
第5行
第6行
第7行
第8行
第9行
第10行
第11行
输出的结果和没用yiled是一样的,看不出来,我们加一个时间戳,并停顿一秒试一下
a, 不用yield
<?php function read($path){ $file = fopen($path, "r"); //输出文本中所有的行,直到文件结束为止。 while(! feof($file)) { $data[] = fgets($file).time()."<br>";//fgets()函数从文件指针中读取一行 } return $data; fclose($file); } $a = read('test.txt'); foreach ($a as $val){ sleep(1); echo $val; }
结果:
第1行 1555488162 第2行 1555488162 第3行 1555488162 第4行 1555488162 第5行 1555488162 第6行 1555488162 第7行 1555488162 第8行 1555488162 第9行 1555488162 第10行 1555488162 第11行1555488162
b.用yield
<?php function read($path){ $file = fopen($path, "r"); //输出文本中所有的行,直到文件结束为止。 while(! feof($file)) { yield fgets($file).time()."<br>";//fgets()函数从文件指针中读取一行 } fclose($file); } $a = read('test.txt'); foreach ($a as $val){ sleep(1); echo $val; }
结果:
第1行 1555487737 第2行 1555487738 第3行 1555487739 第4行 1555487740 第5行 1555487741 第6行 1555487742 第7行 1555487743 第8行 1555487744 第9行 1555487745 第10行 1555487746 第11行1555487747
(3)发现虽然结果一样,但是他们的执行过程是不一样的。