日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > php >内容正文

php

PHP yield简介

發(fā)布時間:2023/12/14 php 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PHP yield简介 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、yield介紹

?文檔介紹說道:生成器函數(shù)的核心是yield關(guān)鍵字。它最簡單的調(diào)用形式看起來像一個return申明,不同之處在于普通return會返回值并終止函數(shù)的執(zhí)行,而yield會返回一個值給循環(huán)調(diào)用此生成器的代碼并且只是暫停執(zhí)行生成器函數(shù)。

?說了這么多到底是個東西呢,只有自己親自動手寫代碼才知道。


二、range函數(shù)探索

?1、首先看下我們常用的一個產(chǎn)生數(shù)組的函數(shù)range()

$ran = range(1, 100);var_dump($ran)//可以看到是一個產(chǎn)生了一個數(shù)組//既然是數(shù)組就來遍歷看下效果吧foreach (range(1, 100) as $num) { echo $num.PHP_EOL;}

?2、現(xiàn)在我們自己來實(shí)現(xiàn)這個range()函數(shù)

function my_range($start,$limit){$arr = []; for($i=$start;$i<=$limit;$i++){$arr[] =$i;}return $arr;}

?了解了這個函數(shù)構(gòu)造后,發(fā)現(xiàn)并沒有什么神奇的地方,那生成器和這個有什么關(guān)系呢,繼續(xù)往下看。


三、內(nèi)存占用

?1、當(dāng)我們遍歷的范圍很小的時候還看不到什么問題,當(dāng)我們要遍歷的數(shù)字很大就會超過PHP的內(nèi)存限制,這下使用生成器就非常有必要了。

?2、我們先看上面的range(1, 100)產(chǎn)生的數(shù)組占用了多少內(nèi)存

$start = memory_get_usage();echo $start.' bytes'.PHP_EOL;$arr = range(1, 100);$end = memory_get_usage();echo $end - $start .' bytes'.PHP_EOL;

?結(jié)果為:8280 bytes
?3、試著增大數(shù)字的范圍可以看到占用的內(nèi)存越來越大,下面是我的一組在CLI模式測試的占用內(nèi)存情況

// 10 728 bytes// 100 8280 bytes// 1000 36952 bytes// 10000 528472 bytes// 100000 6291568 bytes// 1000000 35651696 bytes

?如果繼續(xù)增加到10000000,就會報錯。根據(jù)個人設(shè)置PHP內(nèi)存上限而定。我設(shè)置的是512M。

Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 536870920 bytes) in C:\wamp64\www\phpdemo\yield.php on line 31

?4、如果我們就是要操作很大的數(shù)字遍歷,除了調(diào)整內(nèi)存限制,就無計可施了嘛,這下我們的生成器就要隆重登場了。


四、生成器

?1、上面我們自己實(shí)現(xiàn)了range()方法,這次我們重新使用生成器來實(shí)現(xiàn)這個方法

function my_range($start,$limit){ for($i=$start;$i<=$limit;$i++){yield $i;}}

?2、打印出來,看下返回究竟是什么

$arr = my_range(1,100);var_dump($arr);

?結(jié)果是:

object(Generator)#1 (0) {}

?可見是一個對象,是一個生成器對象,既然是對象那么也就是可以用foreach來遍歷

?3、遍歷生成器

foreach($arr as $num){echo $num.PHP_EOL;}

?看到可以完整遍歷出來,那么與那樣實(shí)現(xiàn)的不同地方,意義在哪里呢。重點(diǎn)來了。

?4、兩者內(nèi)存占用比較
??上面已經(jīng)測試過使用數(shù)組的方式,隨著范圍的增大占用的內(nèi)存劇增,很快就超過了PHP的內(nèi)存上限。
??那么使用生成器占用了多少內(nèi)存呢,來看看就知道了。

$start = memory_get_usage();$arr = my_range(1, 100);$end = memory_get_usage();echo $end - $start .' bytes'.PHP_EOL;

??可以看到只占用了576bytes,當(dāng)然每個人測試的可能都會有點(diǎn)不同,環(huán)境不同,但是這不是重點(diǎn)。

??我們再嘗試增加數(shù)字范圍,可以看到數(shù)字范圍并沒有影響到內(nèi)存占用,也就是可以輕松的遍歷超大數(shù)字。

$start = memory_get_usage();$arr = my_range(1, 100000000);$end = memory_get_usage();echo $end - $start .' bytes'.PHP_EOL;foreach($arr as $num){echo $num.PHP_EOL;}

??這下我們就可以遍歷1到10000000的數(shù)字了,不相信內(nèi)存占用那么低的小伙伴,可以打開任務(wù)管理器毫無波瀾,即時再上調(diào)數(shù)字范圍。

?5、生成器遍歷原理
??生成器既然這么強(qiáng)大,那么他的遍歷原理是什么呢。使用foreach遍歷的時候,相當(dāng)于生成器執(zhí)行了以下操作。

while($arr->valid()){echo $arr->current().PHP_EOL;$arr->next();}//$arr->valid() 判斷生成器是否關(guān)閉//$arr->current() 返回當(dāng)前對象//$arr->next() 繼續(xù)往下執(zhí)行生成器

五、結(jié)后語

??你以為生成器就只有這些用處嗎,當(dāng)然不止。可以使用在很多大量數(shù)據(jù)的獲取場景中,一次性從數(shù)據(jù)庫讀取超多的數(shù)據(jù),一次性從文本讀取超多行文本,都可以這樣處理。
??不僅用于解決內(nèi)存問題,還有其他的用武之地,只因本人才疏學(xué)淺只能先探索這么多了。

總結(jié)

以上是生活随笔為你收集整理的PHP yield简介的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。