哇土 發表於 2022-10-23 11:13:00

php yield详解

<p>&nbsp;一.介绍</p>
<p>&nbsp;</p>
<p>&nbsp;</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 &lt; <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>&lt;?php<br>require '../vendor/autoload.php';<br>class Read{<br>    public static function readLot(){<br>      $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');<br>      $reader-&gt;setReadDataOnly(TRUE);<br>      $spreadsheet = $reader-&gt;load('person.xlsx'); //载入excel表格<br>      $worksheet = $spreadsheet-&gt;getActiveSheet();<br>      $highestRow = $worksheet-&gt;getHighestRow();<br>      $lines = $highestRow - 1;<br>      if ($lines &lt;= 0) {<br>            echo 'Excel表格中没有数据';<br>            die;<br>      }<br>         //获取excel内容<br>         $data = self::yieldData($highestRow, $worksheet);<br>      //遍历生成器<br>         foreach ($data as $k =&gt; $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 &lt;= $highestRow; ++$row) {<br>            $data[$row]['name'] = $worksheet-&gt;getCellByColumnAndRow(1, $row)-&gt;getValue();<br>            $data[$row]['remark'] = $worksheet-&gt;getCellByColumnAndRow(2, $row)-&gt;getValue();<br>            yield $data[$row];<br>      }<br>    }<br><br>}<br>Read::readLot();</pre><br><br>
来源:https://www.cnblogs.com/zxqblogrecord/p/16818170.html
頁: [1]
查看完整版本: php yield详解