php中 yield生成器的簡單使用
阿新 • • 發佈:2022-04-19
原因: 為了防止php變數太大(比如sql出查詢10w條資料放入陣列)導致記憶體溢位。
傳統解決方法: 記憶體溢位時報 **Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes)** 錯誤,以往通過php.ini或者ini_set() 來設定一個程序的更大記憶體,雖然能解決大記憶體問題但不利於介面的效能。
yield原理:假如有100條資料 用foreach就是一次性把資料放到一個數組,記憶體長度佔100。 用yield是一條一條放進去,而且每次放完一條就“銷燬”,然後總記憶體是一條,記憶體長度只佔1
常見使用場景
用法1,處理一個返回值或一個鍵值對
// 傳統
function createRange($number){ $data = []; for($i=1;$i<$number;$i++){ $data[$i] = time(); } return $data; }
// yield
function createRange($number){ for($i=1;$i<$number;$i++){ yield $i => time(); } }$result = createRange(10); // 這裡返回生成器物件(裡面是我們要的陣列data,但記憶體只佔1) foreach($result as $k=>$value){echo $value.$k; }
用法2,處理sql查詢出來的陣列
public static function yieldData($data){ foreach ($data as $datum){ yield $datum; } } $res = Db()->select(); $list = self::yieldData($res); // 邏輯處理foreach($list as $k => &$v){} // 匯出等等 Common::csv($list)
用法3,檔案讀取/匯入功能
function readTxt($path)
{
$handle = fopen($path, 'rb');
while (feof($handle)===false) {
yield fgets($handle);
}
fclose($handle);
}
foreach (readTxt() as $key => $value) {
// 邏輯處理
}
總結
yield生成器允許你 在 foreach 程式碼塊中寫程式碼來迭代一組資料,而不需要在記憶體中建立一個數組,極大提高了程序的記憶體使用率
其它細節可參考:https://segmentfault.com/a/1190000012334856