本文實(shí)例講述了PHP5.5迭代生成器用法。分享給大家供大家參考,具體如下:
PHP5.5引入了迭代生成器的概念,迭代的概念早就在PHP有了,但是迭代生成器是PHP的一個新特性,這跟python3中的迭代生成器類似,看看PHP5.5的迭代生成器如何定義。
<?phpfunction xrange($start, $end, $step = 1) { for ($i = $start; $i <= $end; $i += $step) { yield $i; }}foreach (xrange(1, 1000000) as $num) { echo $num, "/n";} 注意關(guān)鍵字:yield,正是這個yeild關(guān)鍵字構(gòu)建了一個迭代器,這個函數(shù)xrange跟以往的函數(shù)的不同之處就在這里。一般情況都是return一個值,而yield一個值就表示這是個迭代器,每循環(huán)一次這個迭代器就生成這個值,故名為迭代生成器,迭代生成器這個函數(shù)可以進(jìn)行foreach循環(huán),每次都產(chǎn)生一個值。
PHP5.5之前是通過定義類實(shí)現(xiàn)Iterator接口的方式來構(gòu)造迭代器,通過yield構(gòu)造迭代器將更加提升性能節(jié)省系統(tǒng)開銷。
這種方法的優(yōu)點(diǎn)是顯而易見的.它可以讓你在處理大數(shù)據(jù)集合的時候不用一次性的加載到內(nèi)存中,甚至你可以處理無限大的數(shù)據(jù)流。
如上面例子所示,這個迭代器的功能是生成從1到1000000的數(shù)字,循環(huán)輸出,那么使用以往的方式是生成好這1到1000000的數(shù)字到數(shù)組中,將會十分占用內(nèi)存,因為是事先就要生成好所有結(jié)果,而不是用的時候按需生成,也就是說調(diào)用xrange這個迭代器的時候,里面的函數(shù)還沒有真正的運(yùn)行,直到你每一次的迭代。
再看看PHP官網(wǎng)的例子:
<?phpfunction xrange($start, $limit, $step = 1) { for ($i = $start; $i <= $limit; $i += $step) { yield $i; }}echo 'Single digit odd numbers: ';/* * Note that an array is never created or returned, * which saves memory. */foreach (xrange(1, 9, 2) as $number) { echo "$number ";}echo "/n";?> 這里的xrange是一個迭代,功能和range是一樣的,如果使用range函數(shù)的話,那么函數(shù)內(nèi)部實(shí)現(xiàn)會儲存每個迭代的中間過程,即每個中間變量都有 個內(nèi)存空間,那么首先程序使用的內(nèi)存空間就大了,而且分配內(nèi)存,回收內(nèi)存都會導(dǎo)致程序的運(yùn)行時間加長。但是如果使用上yield實(shí)現(xiàn)的xrange函數(shù)的 話,里面所有的中間變量都只使用一個內(nèi)存$i,這樣節(jié)省的時間和空間都會變小。
那么為什么yield會有這樣的效果呢?聯(lián)想到lua中的yield,這里就算是協(xié)程的概念了。在lua語言中,當(dāng)程序運(yùn)行到y(tǒng)ield的時候,使用協(xié)程 將上下文環(huán)境記錄住,然后將程序操作權(quán)歸還到主函數(shù),當(dāng)主函數(shù)調(diào)用resume的時候,會重新喚起協(xié)程,讀取yield記錄的上下文。這樣形成了程序語言 級別的多協(xié)程操作。php 5.5這里的yield也是同樣的道理,當(dāng)程序運(yùn)行到y(tǒng)ield的時候,當(dāng)前程序就喚起協(xié)程記錄上下文,然后主函數(shù)繼續(xù)操作,只是php中沒有使用如 resume一樣的關(guān)鍵字,而是“在使用的時候喚起”協(xié)程。比如上例中的foreach迭代器就能喚起yield。所以上面的這個例子就能理解了。

















