php yield详解
<p> 一.介绍</p><p> </p>
<p> </p>
<p>二.简单例子</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">包含yield的函数可以生成一个generator 对象,可以被foreach 遍历</span>
<span style="color: rgba(0, 0, 0, 1)">function Generator()
{
</span><span style="color: rgba(0, 0, 255, 1)">for</span> ($i = <span style="color: rgba(128, 0, 128, 1)">0</span>; $i < <span style="color: rgba(128, 0, 128, 1)">3</span>; $i++<span style="color: rgba(0, 0, 0, 1)">) {
echo </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">输出存在感1\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">yield</span><span style="color: rgba(0, 0, 0, 1)"> $i;
echo </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">输出存在感2\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
}
}
echo </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">###返回对象1####\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
var_dump(Generator());
echo </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">###返回对象####\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
echo </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">###遍历一次情况####\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (Generator() <span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> $value) {
var_dump($value);
</span><span style="color: rgba(0, 0, 255, 1)">break</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">只遍历一次的情况</span>
<span style="color: rgba(0, 0, 0, 1)">}
echo </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">###遍历一次情况####\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
echo </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">###一直遍历的情况####\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (Generator() <span style="color: rgba(0, 0, 255, 1)">as</span><span style="color: rgba(0, 0, 0, 1)"> $value) {
var_dump($value); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">遍历多次</span>
<span style="color: rgba(0, 0, 0, 1)">
}
echo </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">###一直遍历的情况####\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
###返回对象1####
object(Generator)#1 (0) {
}
###返回对象####
###遍历一次情况####
输出存在感1
int(0)
###遍历一次情况####
###一直遍历的情况####
输出存在感1
int(0)
输出存在感2
输出存在感1
int(1)
输出存在感2
输出存在感1
int(2)
输出存在感2
###一直遍历的情况####
* </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
</pre>
</div>
<pre>1:在调用函数返回的时候,可以发现for里面的语句并没有执行
2:在遍历一次的时候,可以发现调用函数,却没有正常的for循环3次,只循环了一次
3:在遍历一次的情况时,"存在感2"竟然没有调用,在一直遍历的情况下才调用<br><br><br>三. yield 读取excel大文件数据</pre>
<pre><?php<br>require '../vendor/autoload.php';<br>class Read{<br> public static function readLot(){<br> $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');<br> $reader->setReadDataOnly(TRUE);<br> $spreadsheet = $reader->load('person.xlsx'); //载入excel表格<br> $worksheet = $spreadsheet->getActiveSheet();<br> $highestRow = $worksheet->getHighestRow();<br> $lines = $highestRow - 1;<br> if ($lines <= 0) {<br> echo 'Excel表格中没有数据';<br> die;<br> }<br> //获取excel内容<br> $data = self::yieldData($highestRow, $worksheet);<br> //遍历生成器<br> foreach ($data as $k => $v) {<br> //使用的时候就会读取一条出来,就不会把所有数据读取放在$data里面,造成内存不足,这就是yield的强大之处<br> var_dump($v).PHP_EOL;<br> echo $k;<br> echo '-----';<br> }<br><br> }<br> //包含yield关键字的函数会生成生成器generate<br> private static function yieldData($highestRow, $worksheet)<br> {<br> for ($row = 2; $row <= $highestRow; ++$row) {<br> $data[$row]['name'] = $worksheet->getCellByColumnAndRow(1, $row)->getValue();<br> $data[$row]['remark'] = $worksheet->getCellByColumnAndRow(2, $row)->getValue();<br> yield $data[$row];<br> }<br> }<br><br>}<br>Read::readLot();</pre><br><br>
来源:https://www.cnblogs.com/zxqblogrecord/p/16818170.html
頁:
[1]