PHP yield简介
一、yield介紹
?文檔介紹說道:生成器函數的核心是yield關鍵字。它最簡單的調用形式看起來像一個return申明,不同之處在于普通return會返回值并終止函數的執行,而yield會返回一個值給循環調用此生成器的代碼并且只是暫停執行生成器函數。
?說了這么多到底是個東西呢,只有自己親自動手寫代碼才知道。
二、range函數探索
?1、首先看下我們常用的一個產生數組的函數range()
$ran = range(1, 100);var_dump($ran)//可以看到是一個產生了一個數組//既然是數組就來遍歷看下效果吧foreach (range(1, 100) as $num) { echo $num.PHP_EOL;}?2、現在我們自己來實現這個range()函數
function my_range($start,$limit){$arr = []; for($i=$start;$i<=$limit;$i++){$arr[] =$i;}return $arr;}?了解了這個函數構造后,發現并沒有什么神奇的地方,那生成器和這個有什么關系呢,繼續往下看。
三、內存占用
?1、當我們遍歷的范圍很小的時候還看不到什么問題,當我們要遍歷的數字很大就會超過PHP的內存限制,這下使用生成器就非常有必要了。
?2、我們先看上面的range(1, 100)產生的數組占用了多少內存
$start = memory_get_usage();echo $start.' bytes'.PHP_EOL;$arr = range(1, 100);$end = memory_get_usage();echo $end - $start .' bytes'.PHP_EOL;?結果為:8280 bytes
?3、試著增大數字的范圍可以看到占用的內存越來越大,下面是我的一組在CLI模式測試的占用內存情況
?如果繼續增加到10000000,就會報錯。根據個人設置PHP內存上限而定。我設置的是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、如果我們就是要操作很大的數字遍歷,除了調整內存限制,就無計可施了嘛,這下我們的生成器就要隆重登場了。
四、生成器
?1、上面我們自己實現了range()方法,這次我們重新使用生成器來實現這個方法
function my_range($start,$limit){ for($i=$start;$i<=$limit;$i++){yield $i;}}?2、打印出來,看下返回究竟是什么
$arr = my_range(1,100);var_dump($arr);?結果是:
object(Generator)#1 (0) {}?可見是一個對象,是一個生成器對象,既然是對象那么也就是可以用foreach來遍歷
?3、遍歷生成器
foreach($arr as $num){echo $num.PHP_EOL;}?看到可以完整遍歷出來,那么與那樣實現的不同地方,意義在哪里呢。重點來了。
?4、兩者內存占用比較
??上面已經測試過使用數組的方式,隨著范圍的增大占用的內存劇增,很快就超過了PHP的內存上限。
??那么使用生成器占用了多少內存呢,來看看就知道了。
??可以看到只占用了576bytes,當然每個人測試的可能都會有點不同,環境不同,但是這不是重點。
??我們再嘗試增加數字范圍,可以看到數字范圍并沒有影響到內存占用,也就是可以輕松的遍歷超大數字。
$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的數字了,不相信內存占用那么低的小伙伴,可以打開任務管理器毫無波瀾,即時再上調數字范圍。
?5、生成器遍歷原理
??生成器既然這么強大,那么他的遍歷原理是什么呢。使用foreach遍歷的時候,相當于生成器執行了以下操作。
五、結后語
??你以為生成器就只有這些用處嗎,當然不止。可以使用在很多大量數據的獲取場景中,一次性從數據庫讀取超多的數據,一次性從文本讀取超多行文本,都可以這樣處理。
??不僅用于解決內存問題,還有其他的用武之地,只因本人才疏學淺只能先探索這么多了。
總結
以上是生活随笔為你收集整理的PHP yield简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过yum安装Oracle instan
- 下一篇: ThinkPHP3.2.3从php5升级