php使用yield進行大數據量處理
目錄 隱藏
1 概述
2 生成器函數
3 yield關鍵字
4 一個簡單的例子
5 遍歷數據庫實例
5.1 未使用生成器
5.2 使用生成器
概述
當我們需要使用php來處理大數據量時,例如循環(huán)數據庫的所有記錄,這個記錄可能會很大,例如100萬行,那么通過傳統(tǒng)的辦法就行不通了。首先通過web訪問,php有超時時間,默認是30秒。那么就只能通過php cli的方式來執(zhí)行,這樣就沒有超時時間了,但由于數據量太大,php循環(huán)時需要將數據全部載入內存中執(zhí)行,由于數據量太大,php會報Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes)的錯誤。php默認的內存限制為128M,雖然可以通過修改php.ini中memory_limit的選項的值來提高內存限制,但始終不是最優(yōu)的解決辦法。PHP通過生成器函數可以極大節(jié)省內存開銷。
生成器函數
生成器函數看起來像普通函數——不同的是普通函數返回一個值,而生成器可以 yield 生成多個想要的值。任何包含 yield 的函數都是一個生成器函數。
當一個生成器被調用的時候,它返回一個可以被遍歷的對象.當你遍歷這個對象的時候(例如通過一個foreach循環(huán)),PHP 將會在每次需要值的時候調用對象的遍歷方法,并在產生一個值之后保存生成器的狀態(tài),這樣它就可以在需要產生下一個值的時候恢復調用狀態(tài)。
yield關鍵字
生成器函數的核心是yield關鍵字。yield關鍵字看起來像一個return申明,不同之處在于普通return會返回值并終止函數的執(zhí)行,而yield會返回一個值給循環(huán)調用此生成器的代碼并且只是暫停執(zhí)行生成器函數。
一個簡單的例子
以上例子會輸出:
遍歷數據庫實例
例如當前我們需要循環(huán)數據庫的emp表,這個表中有100萬行記錄,我們需要循環(huán)并修改mgr的字段的值。
未使用生成器
這在數據量小時并沒有什么問題,但數據量比較大的話,就無法執(zhí)行了,會報內存超過限制的錯誤。
使用生成器
通過test_yield這個生成器函數,程序可以正常執(zhí)行,且內存不會超限。
