婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > PHP 生成器的使用詳解

PHP 生成器的使用詳解

熱門標簽:凱立德地鐵站地圖標注 手機外呼系統什么原理 天津電銷外呼系統違法嗎 合肥ai電銷機器人費用 上海400客服電話怎么申請 400電話個人能不能辦理 溫州外呼系統招商 滄州電銷外呼系統價格 銀行信貸電話機器人

什么是生成器?

聽著高大上的名字,感覺像是創造什么東西的一個功能,實際上,生成器是一個用于迭代的迭代器。它提供了一種更容易的方式來實現簡單的對象迭代,相比較定義類實現Iterator接口的方式,性能開銷和復雜性大大降低。

說了半天不如直接看看代碼更直觀。

function test1()
{
    for ($i = 0; $i  3; $i++) {
        yield $i + 1;
    }
    yield 1000;
    yield 1001;
}

foreach (test1() as $t) {
    echo $t, PHP_EOL;
}

// 1
// 2
// 3
// 1000
// 1001

就是這么簡單的一段代碼。首先,生成器必須在方法中并使用 yield 關鍵字;其次,每一個 yield 可以看作是一次 return ;最后,外部循環時,一次循環取一個 yield 的返回值。在這個例子,循環三次返回了1、2、3這三個數字。然后在循環外部又寫了兩行 yield 分別輸出了1000和1001。因此,外部的 foreach 一共循環輸出了五次。

很神奇吧,明明是一個方法,為什么能夠循環它而且還是很奇怪的一種返回循環體的格式。我們直接打印這個 test() 方法看看打印的是什么:

// 是一個生成器對象
var_dump(test1());

// Generator Object
// (
// )

當使用了 yield 進行內容返回后,返回的是一個 Generator 對象。這個對象就叫作生成器對象,它不能直接被 new 實例化,只能通過生成器函數這種方式返回。這個類包含 current() 、 key() 等方法,而且最主要的這個類實現了 Iterator 接口,所以,它就是一個特殊的迭代器類。

Generator implements Iterator {
    /* 方法 */
    public current ( void ) : mixed
    public key ( void ) : mixed
    public next ( void ) : void
    public rewind ( void ) : void
    public send ( mixed $value ) : mixed
    public throw ( Exception $exception ) : void
    public valid ( void ) : bool
    public __wakeup ( void ) : void
}

生成器有什么用?

搞了半天不就是個迭代器嘛?搞這么麻煩干嘛,直接用迭代器或者在方法中直接返回一個數組不就好了嗎?沒錯,正常情況下真的沒有這么麻煩,但是如果是在數據量特別大的情況下,這個生成器就能發揮它的強大威力了。生成器最最強大的部分就在于,它不需要一個數組或者任何的數據結構來保存這一系列數據。每次迭代都是代碼執行到 yield 時動態返回的。因此,生成器能夠極大的節約內存。

// 內存占用測試
$start_time = microtime(true);
function test2($clear = false)
{
    $arr = [];
    if($clear){
        $arr = null;
        return;
    }
    for ($i = 0; $i  1000000; $i++) {
        $arr[] = $i + 1;
    }
    return $arr;
}
$array = test2();
foreach ($array as $val) {
}
$end_time = microtime(true);

echo "time: ", bcsub($end_time, $start_time, 4), PHP_EOL;
echo "memory (byte): ", memory_get_usage(true), PHP_EOL;

// time: 0.0513
// memory (byte): 35655680

$start_time = microtime(true);
function test3()
{
    for ($i = 0; $i  1000000; $i++) {
        yield $i + 1;
    }
}
$array = test3();
foreach ($array as $val) {

}
$end_time = microtime(true);

echo "time: ", bcsub($end_time, $start_time, 4), PHP_EOL;
echo "memory (byte): ", memory_get_usage(true), PHP_EOL;

// time: 0.0517
// memory (byte): 2097152

上述代碼只是簡單的進行 1000000 個循環后獲取結果,不過也可以直觀地看出。使用生成器的版本僅僅消耗了 2M 的內存,而未使用生成器的版本則消耗了 35M 的內存,直接已經10多倍的差距了,而且越大的量差距超明顯。因此,有大神將生成器說成是PHP中最被低估了的一個特性。

生成器的應用

接下來我們來看看生成器的一些基本的應用方式。

返回空值以及中斷

生成器當然也可以返回空值,直接 yield; 不帶任何值就可以返回一個空值了。而在方法中直接使用 return; 也可以用來中斷生成器的繼續執行。下面的代碼我們在 \i = 4; 的時候返回的是個空值,也就是不會輸出 5 (因為我們返回的是i=4;的時候返回的是個空值,也就是不會輸出5(因為我們返回的是i + 1 )。然后在 $i == 7 的時候使用 return; 中斷生成器的繼續執行,也就是循環最多只會輸出到 7 就結束了。

// 返回空值以及中斷
function test4()
{
    for ($i = 0; $i  10; $i++) {
        if ($i == 4) {
            yield; // 返回null值
        }
        if ($i == 7) {
            return; // 中斷生成器執行
        }
        yield $i + 1;
    }
}

foreach (test4() as $t) {
    echo $t, PHP_EOL;
}


// 1
// 2
// 3
// 4

// 5
// 6
// 7

返回鍵值對形式

不要驚訝,生成器真的是可以返回鍵值對形式的可遍歷對象供 foreach 使用的,而且語法非常好記: yield key => value; 是不是和數組項的定義形式一模一樣,非常直觀好理解。

function test5()
{
    for ($i = 0; $i  10; $i++) {
        yield 'key.' . $i => $i + 1;
    }
}

foreach (test5() as $k=>$t) {
    echo $k . ':' . $t, PHP_EOL;
}

// key.0:1
// key.1:2
// key.2:3
// key.3:4
// key.4:5
// key.5:6
// key.6:7
// key.7:8
// key.8:9
// key.9:10

外部傳遞數據

我們可以通過 Generator::send 方法來向生成器中傳入一個值。傳入的這個值將會被當做生成器當前 yield 的返回值。然后我們根據這個值可以做一些判斷,比如根據外部條件中斷生成器的執行。

function test6()
{
    for ($i = 0; $i  10; $i++) {
        // 正常獲取循環值,當外部send過來值后,yield獲取到的就是外部傳來的值了
        $data = (yield $i + 1);
        if($data == 'stop'){
            return;
        }
    }
}
$t6 = test6();
foreach($t6 as $t){
    if($t == 3){
        $t6->send('stop');
    }
    echo $t, PHP_EOL;
}

// 1
// 2
// 3

上述代碼理解起來可能比較繞,但是注意記住注釋的那行話就行了(正常獲取循環值,當外部send過來值后,yield獲取到的就是外部傳來的值了)。另外,變量獲取 yield 的值,必須要用括號括起來。

yield from 語法

yield from 語法其實就是指的從另一個可迭代對象中一個一個的獲取數據并形成生成器返回。直接看代碼

function test7()
{
    yield from [1, 2, 3, 4];
    yield from new ArrayIterator([5, 6]);
    yield from test1();
}
foreach (test7() as $t) {
    echo 'test7:', $t, PHP_EOL;
}

// test7:1
// test7:2
// test7:3
// test7:4
// test7:5
// test7:6
// test7:1
// test7:2
// test7:3
// test7:1000

在 test7() 方法中,我們使用 yield from 分別從普通數組、迭代器對象、另一個生成器中獲取數據并做為當前生成器的內容進行返回。

小驚喜

生成器可以用count獲取數量嗎?

抱歉,生成器是不能用count來獲取它的數量的。

$c = count(test1()); // Warning: count(): Parameter must be an array or an object that implements Countable
// echo $c, PHP_EOL;

使用 count 來獲取生成器的數量將直接報 Warning 警告。直接輸出將會一直顯示是 1 ,因為 count 的特性(強制轉換成數組都會顯示 1 )。

使用生產器來獲取斐波那契數列

// 利用生成器生成斐波那契數列
function fibonacci($item)
{
    $a = 0;
    $b = 1;
    for ($i = 0; $i  $item; $i++) {
        yield $a;
        $a = $b - $a;
        $b = $a + $b;
    }
}

$fibo = fibonacci(10);
foreach ($fibo as $value) {
    echo "$value\n";
}

這段代碼就不多解釋了,非常直觀的一段代碼了。

總結

生成器絕對是PHP中的一個隱藏的寶藏,不僅是對于內存節約來說,而且語法其實也非常的簡潔明了。我們不需要在方法內部再多定義一個數組去存儲返回值,直接 yield 一項一項的返回就可以了。在實際的項目中完全值得嘗試一把,但是嘗試完了別忘了和小伙伴們分享,大部分人可能真的沒有接觸過這個特性哦?。?/p>

測試代碼: github.com/zhangyue050…

以上就是PHP 生成器的使用詳解的詳細內容,更多關于PHP 生成器的資料請關注腳本之家其它相關文章!

您可能感興趣的文章:
  • PHP Web表單生成器案例分析
  • PHP迭代器和生成器用法實例分析
  • PHP生成器(generator)和協程的實現方法詳解
  • PHP生成器功能與用法實例分析
  • PHP中你可能忽略的性能優化利器:生成器
  • PHP十六進制顏色隨機生成器功能示例
  • PHP新特性詳解之命名空間、性狀與生成器
  • php驗證碼生成器
  • thinkPHP連接sqlite3數據庫的實現方法(附Thinkphp代碼生成器下載)
  • PHP5.5迭代生成器用法實例詳解

標簽:溫州 白城 怒江 金華 七臺河 酒泉 洛陽 赤峰

巨人網絡通訊聲明:本文標題《PHP 生成器的使用詳解》,本文關鍵詞  PHP,生,成器,的,使用,詳解,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《PHP 生成器的使用詳解》相關的同類信息!
  • 本頁收集關于PHP 生成器的使用詳解的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    成人av在线一区二区三区| 亚洲6080在线| 精品国产免费人成电影在线观看四季 | 中文字幕av不卡| 久久精品视频一区二区三区| 久久久久久久久久久黄色| 日韩免费福利电影在线观看| 日韩视频免费直播| 欧美大白屁股肥臀xxxxxx| 欧美zozo另类异族| 久久综合精品国产一区二区三区| 日韩免费高清av| 久久久www成人免费毛片麻豆| 国产视频视频一区| **性色生活片久久毛片| 亚洲成av人片在线观看无码| 免费一级片91| 粉嫩蜜臀av国产精品网站| 99国产精品国产精品毛片| 91久久久免费一区二区| 91精品国产麻豆| 欧美精品一区在线观看| 国产精品麻豆一区二区| 一区二区三区在线观看视频| 日本午夜精品一区二区三区电影| 欧美亚洲国产一区在线观看网站 | 一级日本不卡的影视| 香蕉成人伊视频在线观看| 狠狠色综合播放一区二区| 92国产精品观看| 日韩写真欧美这视频| 国产精品毛片久久久久久久| 一区二区三区日韩精品视频| 青青草国产成人av片免费| 成人av在线资源网站| 欧美日韩免费高清一区色橹橹| 久久久久久久久久久久久夜| 夜夜亚洲天天久久| 粉嫩嫩av羞羞动漫久久久| 在线成人小视频| 亚洲欧美另类综合偷拍| 美女尤物国产一区| 在线看国产日韩| 欧美国产97人人爽人人喊| 亚洲永久免费av| 久久国产三级精品| 欧美三级在线视频| 中文字幕综合网| 国产精品一区一区| 精品国产污污免费网站入口| 亚洲va韩国va欧美va精品 | 五月婷婷欧美视频| 懂色av一区二区夜夜嗨| 亚洲欧美另类综合偷拍| 成人午夜免费视频| 久久亚洲一区二区三区明星换脸| 亚洲高清不卡在线| 在线一区二区三区四区五区 | 精品黑人一区二区三区久久 | 久久―日本道色综合久久| 午夜亚洲福利老司机| 91久久一区二区| 亚洲免费观看高清完整版在线观看 | 91社区在线播放| 欧美国产激情二区三区| 国产精品一区二区久久不卡| 日韩一区二区三区av| 日本欧美一区二区三区| 欧美日韩精品一区视频| 亚洲大片免费看| 欧美日韩一本到| 日本成人在线电影网| 欧美美女直播网站| 青青草国产成人99久久| 日韩欧美一区中文| 久久丁香综合五月国产三级网站| 日韩免费观看2025年上映的电影| 久久99深爱久久99精品| 亚洲精品在线一区二区| 国产不卡一区视频| 亚洲天堂久久久久久久| 在线观看精品一区| 三级亚洲高清视频| 欧美sm美女调教| 国产精品99久久久久久有的能看| 欧美激情一二三区| 91美女精品福利| 日韩va欧美va亚洲va久久| 日韩欧美一区二区视频| 大桥未久av一区二区三区中文| 国产精品国产成人国产三级| 欧美主播一区二区三区| 青青草成人在线观看| 久久久不卡网国产精品二区| 91麻豆高清视频| 日本午夜精品视频在线观看| 国产欧美日韩不卡免费| 欧美性做爰猛烈叫床潮| 久久99久久精品| 日韩美女视频一区二区| 欧美一级理论性理论a| 成人性生交大片| 亚洲国产精品久久人人爱| 精品国产人成亚洲区| 91在线国产福利| 精品一区二区影视| 亚洲一区二区高清| 久久久久久9999| 欧美日韩aaaaa| 成人av午夜电影| 免费欧美日韩国产三级电影| 中文字幕一区二区三区四区| 欧美一区二区三区思思人| 91婷婷韩国欧美一区二区| 久久69国产一区二区蜜臀| 亚洲精品成人天堂一二三| 26uuu国产在线精品一区二区| 91麻豆国产精品久久| 国产一区二区毛片| 日韩精品乱码av一区二区| 中文字幕在线一区免费| 久久婷婷久久一区二区三区| 欧美另类久久久品| 欧美艳星brazzers| 99精品欧美一区二区三区小说| 麻豆精品视频在线观看| 亚洲成av人片观看| 亚洲激情av在线| 亚洲视频免费在线| 国产精品美女久久久久久久 | 日韩欧美一区二区视频| 日本道精品一区二区三区| 成人免费视频一区二区| 国产露脸91国语对白| 日韩成人精品在线| 婷婷国产v国产偷v亚洲高清| 亚洲精品亚洲人成人网在线播放| 欧美高清在线一区二区| 国产欧美日韩激情| 国产精品嫩草久久久久| 日本一区二区视频在线观看| 欧美tickling挠脚心丨vk| 欧美精品日韩综合在线| 欧美嫩在线观看| 欧美一级国产精品| 精品日韩在线一区| 久久一二三国产| 亚洲国产精品精华液ab| 国产精品日产欧美久久久久| 国产精品色在线观看| 久久久电影一区二区三区| 久久―日本道色综合久久| 国产欧美一区二区三区网站 | 久久综合五月天婷婷伊人| 亚洲精品在线观看网站| 国产欧美日韩不卡免费| 亚洲国产电影在线观看| 亚洲黄色av一区| 香蕉加勒比综合久久| 老司机午夜精品| 国产精品888| 日本久久一区二区三区| 7878成人国产在线观看| 精品剧情在线观看| 国产精品剧情在线亚洲| 亚洲免费观看视频| 蜜桃久久av一区| 不卡视频一二三四| 欧美三级一区二区| 久久色成人在线| 亚洲精品一二三区| 激情图区综合网| 色综合天天性综合| 欧美一区二区成人| 国产精品亲子乱子伦xxxx裸| 亚洲精品久久久蜜桃| 麻豆中文一区二区| 91蜜桃在线观看| 337p粉嫩大胆噜噜噜噜噜91av| 国产精品动漫网站| 日本特黄久久久高潮| 99综合影院在线| 欧美本精品男人aⅴ天堂| 综合分类小说区另类春色亚洲小说欧美| 亚洲国产日韩综合久久精品| 国产精品一区二区三区四区| 欧美午夜一区二区三区 | 色噜噜狠狠成人网p站| 欧美大片免费久久精品三p| 悠悠色在线精品| 成人午夜短视频| 日韩欧美的一区二区| 一区二区免费在线| thepron国产精品| 精品国产凹凸成av人导航| 一区二区三区精品视频| 粉嫩久久99精品久久久久久夜| 日韩一区二区免费在线电影| 亚洲精选免费视频| 成av人片一区二区|