這篇文章給大家介紹的內容是關於PHP產生器Generators的簡單解析,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所協助。
什麼是產生器Generators
產生器允許你在 foreach 代碼塊中寫代碼來迭代一組資料而不需要在記憶體中建立一個數組, 那會使你的記憶體達到上限,或者會佔據可觀的處理時間。相反,你可以寫一個產生器函數,就像一個普通的自訂函數一樣, 和普通函數只返回一次不同的是, 產生器可以根據需要 yield 多次,以便產生需要迭代的值。
一個簡單的例子就是使用產生器來重新實現 range() 函數。 標準的 range() 函數需要在記憶體中產生一個數組包含每一個在它範圍內的值,然後返回該數組, 結果就是會產生多個很大的數組。 比如,調用 range(0, 10000) 將導致記憶體佔用超過 4 MB。
例子代碼:
<?php/** * Created by PhpStorm. * User: chenbotome@163.com * Date: 2018/7/30 * Time: 上午11:29 */$start = xdebug_memory_usage();$num = 10000;function rangeWithGenerators($start, $limit, $step = 1) { if ($start < $limit) { if ($step <= 0) { throw new LogicException('Step must be +ve'); } for ($i = $start; $i <= $limit; $i += $step) { yield $i; } } else { if ($step >= 0) { throw new LogicException('Step must be -ve'); } for ($i = $start; $i >= $limit; $i += $step) { yield $i; } }}if ($argc === 1) { $iterate = rangeWithGenerators(0, $num, 1); foreach ($iterate as $value){ echo $value . "\n"; } //var_dump(iterator_to_array($iterate));}if ($argc === 2) { $test = range(0, $num, 1); foreach ($test as $value) { echo $value . "\n"; }}$end = xdebug_memory_usage();echo sprintf("記憶體消耗量%s\n", convert($end-$start));function convert($size){ $unit=array('b','kb','mb','gb','tb','pb'); return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];}
環境
執行命令
測試結果論述
通過代碼的執行,比較除了PHP標準函數rang()和自訂函數rangeWithGenerators()之間的異同。實現了同樣的目的,卻消耗著不同的記憶體,產生器的優點顯而易見。
rangeWithGenerators()使用了產生器,而產生器的關鍵就是使用yield關鍵詞,yield常見的使用涉及到foreach和for兩個流程式控制制語句。rangeWithGenerators()中for迴圈yield變數$i(yield可理解為產生-值,如同return可理解為返回-值)。
rangeWithGenerators()函數返回的便是一個產生器Generators( 使用var_dump($iterate)查看其類型 )。
既然rangeWithGenerators()函數返回的是一個產生器,我們可以使用以下兩種方式來使用:
foreach迴圈該Generators,本例子中則使用該方法讀取Generators。
PHP標準函數iterator_to_array(),該函數將Generators轉換為一個Array。