首頁 >後端開發 >php教程 >php生成器使用方法

php生成器使用方法

小云云
小云云原創
2018-03-26 09:50:501649瀏覽

一般我們在迭代一組數據的時候,需要創建一個數據,如果數組很大,則會消耗很大性能,甚至造成內存不足拋出error
比如:

//Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in D:\php\test\index.php on line 5range(1, 100000000);

PHP5 .5引入了迭代生成器的概念,迭代的概念早就在PHP有了,但是迭代生成器是PHP的一個新特性,這跟python3中的迭代生成器類似,看看PHP5.5的迭代生成器如何定義。
以下範例實作了生成器,每當產生一個數組元素則用yield關鍵字返回,並且執行函數暫停,當執行函數next方法時,則會從上一次被yield的位置開始繼續執行,如下例,只會產生中間變數$i

function xrange($start, $limit, $step = 1) {    for ($i = $start; $i <= $limit; $i += $step) {
        yield $i;
    }
} 
foreach (xrange(1, 9, 1) as $number) {    echo "$number ";
}

這裡的xrange是一個迭代,函數和range是一樣的,如果使用range函數的話,那麼函數內部實作會儲存每個迭代的中間過程,即每個中間變數都有個記憶體空間,那麼首先程式使用的記憶體空間就大了,而且分配內存,回收記憶體都會導致程式的運行時間加長。但如果使用上yield實現的xrange函數的 話,裡面所有的中間變數都只使用一個記憶體$i,這樣節省的時間和空間都會變小。

那為什麼yield會有這樣的效果呢?聯想到lua中的yield,這裡就算是協程的概念了。在lua語言中,當程式運行到yield的時候,使用協程將上下文環境記錄住,然後將程式操作權歸還到主函數,當主函數呼叫resume的時候,會重新喚起協程,讀取yield記錄的上下文。這樣形成了程式語言 層級的多協程操作。 php 5.5這裡的yield也是同樣的道理,當程式運行到yield的時候,當前程式就喚起協程記錄上下文,然後主函數繼續操作,只是php中沒有使用如resume一樣的關鍵字,而是「在使用的時候喚起」協程。例如上例中的foreach迭代器就能喚起yield。所以上面的這個例子就能理解了。

再例如:

function xrange($start, $end, $step = 1) {    for ($i = $start; $i <= $end; $i += $step) {
      yield $i;
    }
}foreach (xrange(1, 1000000) as $num) {    echo $num, "\n";
}

注意關鍵字:yield,正是這個yeild關鍵字建立了一個迭代器,這個函數xrange跟以往的函數的不同之處就在這裡。一般情況都是return一個值,而yield一個值就表示這是個迭代器,每循環一次這個迭代器就產生這個值,故名為迭代生成器,迭代生成器這個函數可以進行foreach循環,每次都產生一個值。

PHP5.5之前是透過定義類別實作Iterator介面的方式來建構迭代器,透過yield建構迭代器將更加提升效能節省系統開銷。

這種方法的優點是顯而易見的.它可以讓你在處理大數據集合的時候不用一次性的加載到內存中,甚至你可以處理無限大的數據流。

如上面範例所示,這個迭代器的功能是產生從1到1000000的數字,循環輸出,那麼使用以往的方式是產生好這1到1000000的數字到數組中,將會十分佔用內存,因為是事先就要生成好所有結果,而不是用的時候按需生成,也就是說調用xrange這個迭代器的時候,裡面的函數還沒有真正的運行,直到你每一次的迭代。

相關推薦:

PHP產生器如何使用

#PHP產生器的功能與用法詳解

php產生器詳細介紹

#

以上是php生成器使用方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn