什么是 “yield”
生成器函数看上去就像一个普通函数, 除了不是返回一个值之外, 生成器会根据需求产生更多的值。
1 2 3 4 5 6 7 8 9
| function getValues() { return 'value'; } var_dump(getValues()); function getValues() { yield 'value'; } var_dump(getValues());
|
a. 使用 yield, 你也可以使用 return
1 2 3 4 5 6 7
| function getValues() { yield 'value'; return 'returnValue'; } $values = getValues(); foreach ($values as $value) {} echo $values->getReturn();
|
b. 返回键值对
1 2 3 4 5 6 7
| function getValues() { yield 'key' => 'value'; } $values = getValues(); foreach ($values as $key => $value) { echo $key . ' => ' . $value; }
|
实际开发应用
很多PHP开发者不了解生成器,其实主要是不了解应用领域。那么,生成器在实际开发中有哪些应用?
读取超大文件
PHP开发很多时候都要读取大文件,比如csv文件、text文件,或者一些日志文件。这些文件如果很大,比如5个G。这时,直接一次性把所有的内容读取到内存中计算不太现实。
这里生成器就可以派上用场啦。简单看个例子:读取text文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?php header("content-type:text/html;charset=utf-8"); function readTxt() { $handle = fopen("./test.txt", 'rb'); while (feof($handle)===false) { yield fgets($handle); } fclose($handle); } foreach (readTxt() as $key => $value) { echo $value.'<br />'; }
|
通过上图的输出结果我们可以看出代码完全正常。
但是,背后的代码执行规则却一点儿也不一样。使用生成器读取文件,第一次读取了第一行,第二次读取了第二行,以此类推,每次被加载到内存中的文字只有一行,大大的减小了内存的使用。
这样,即使读取上G的文本也不用担心,完全可以像读取很小文件一样编写代码。
PS: 还有js生成器generator需要深入学习一下
案例参考来自https://blog.csdn.net/Csoap2/article/details/87620204