現代PHP 生成器的建立和使用

2022-09-12 01:09:22 字數 1911 閱讀 6385

概述

生成器是 php 5.5 引入的新特性,但是目測很少人用到它,其實這是個非常有用的功能。

生成器和迭代器有點類似,但是與標準的php迭代器不同,php生成器不要求類實現iterator介面,從而減輕了類的開銷和負擔。生成器會根據需求每次計算並產出需要迭代的值,這對應用的效能有很大的影響:試想假如標準的php迭代器經常在記憶體中執行迭代操作,這要預先計算出資料集,效能低下;如果要使用特定方式計算大量資料,如操作excel表資料,對效能影響更甚。此時我們可以使用生成器,即時計算並產出後續值,不占用寶貴的記憶體空間。

建立生成器

生成器的建立方式很簡單,因為生成器就是php函式,只不過要在函式中一次或多次使用yield關鍵字。與普通的php函式不同的是,生成器從不返回值,只產出值。下面是乙個簡單的生成器實現:

function getcontent()
很簡單吧!呼叫此生成器函式時,php會返回乙個屬於generator類的物件,這個物件可以使用foreach函式迭代,每次迭代,php會要求generator例項計算並提供下乙個要迭代的值。

生成器的優雅體現在每次產出乙個值之後,生成器的內部狀態都會停頓;向生成器請求下乙個值時,內部狀態又會恢復。生成器內部的狀態會一直在停頓和恢復之間切換,直到抵達函式定義體的末尾或遇到空的return語句為止。

我們可以使用下面的**呼叫並迭代上面定義的生成器:

foreach(getcontent() as $yieldedvalue)
上面**輸出如下:

內容1

內容2內容3

使用生成器

下面我們實現乙個簡單的函式用於生成乙個範圍內的數值,以此說明生成器是如何節省記憶體的。首先我們通過迭代器來實現:

function makerange($length) 

return $dataset;

}$customrange = makerange(1000000);

foreach ($customrange as $i)

此時執行會報錯,提示超出單個php程序記憶體限制(要為100萬個數字提供記憶體空間):

下面我們來改進實現方案,使用生成器實現如下:

function makerange($length) 

}foreach (makerange(1000000) as $i)

再次執行就可以毫無壓力的列印出結果,因為生成器每次只需要為乙個整數分配記憶體。

此外,乙個常用的使用案例就是使用生成器迭代流資源(檔案、音訊等)。假設我們想要迭代乙個大小為4gb的csv檔案,而虛擬私有伺服器(vps)只允許php使用1gb記憶體,因此不能把整個檔案都載入到記憶體中,下面的**展示了如何使用生成器完成這種操作:

function getrows($file) 

while (feof($handle) === false)

fclose($handle);

}foreach (getrows($file) as $row)

上述示例一次只會為csv檔案中的一行分配記憶體,而不會把整個4gb的csv檔案都讀取到記憶體中。

總結生成器是功能多樣性和簡潔性之間的折中方案,生成器只是向前進的迭代器,這意味著不能使用生成器在資料集中執行後退、快進或查詢操作,只能讓生成器計算並產出下乙個值。迭代大型資料集或數列時最適合使用生成器,因為這樣占用的系統記憶體最少。生成器也能完成迭代器能完成的簡單任務,而且使用的**更少。

總而言之,生成器並沒有為php新增新功能,不過使用生成器大大簡化了某些任務,而且使用的記憶體更少,如果需要更多功能,例如在資料集中執行後退、快進以及查詢功能,最好自己編寫實現iterator介面的類,或者使用php標準庫(spl)中某個原生的迭代器(

生成器 PHP的生成器yield 原創

在php 5.5中,php多了乙個新的特性,那就是生成器 generator 生成器提供了一種更簡單的方法來實現簡單的物件迭代。下面的manual的引用 生成器提供了一種更容易的方法來實現簡單的物件迭代,相比較定義類實現 iterator 介面的方式,效能開銷和複雜性大大降低。生成器允許你在 for...

PHP的生成器

參考文章 php生成器是5.5.0引入的功能,生成器實際上就是簡單的迭代器。生成器會根據需求計算產出迭代的值,而標準的php迭代器經常在記憶體中執行迭代操作,這要預先計算出資料集,效能較低。如果使用特定的防護計算大量資料,可以使用生成器,即時計算並產出後續值,不占用記憶體。yield和生成器 相比較...

php的生成器

如果是做python或者其他語言的小夥伴,對於生成器應該不陌生。但很多php開發者或許都不知道生成器這個功能,可能是因為生成器是php 5.5.0才引入的功能,也可以是生成器作用不是很明顯。但是,生成器功能的確非常有用。直接講概念估計你聽完還是一頭霧水,所以我們先來說說優點,也許能勾起你的興趣。那麼...