實例講解PHP裡的Iterator和Generator

藏色散人
發布: 2023-04-10 11:58:02
轉載
2398 人瀏覽過

#在講解產生器之前先介紹迭代器:

在PHP 中,通常情況下遍歷數組使用foreach 來遍歷。

如果我們要想讓一個物件可以遍歷呢?

PHP 為我們提供了 Iterator 接口,只要實作了這個接口,這個物件就可以透過 foreach 來迭代。

範例如下:

class myIterator implements Iterator {
    private $index = 0;
    private $data = '';

    public function __construct($data) {
        $this->index = 0;
        $this->data = $data;
    }

    function rewind() {
        $this->index = 0;
    }

    function current() {
        return $this->data[$this->index];
    }

    function key() {
        return $this->index;
    }

    function next() {
        ++$this->index;
    }

    function valid() {
        return isset($this->data[$this->index]);
    }
}

$it = new myIterator(array(
    "hello",
    "php",
    "iterator",
));
foreach($it as $key => $value) {
    echo "$key : $value<br>";
}
登入後複製

我們透過foreach遍歷$it 時,PHP 會自己依序呼叫:

rewind()    重置到第一個元素
valid()     檢查目前位置是否有效
current()   返回目前元素
key()       檢查目前元素的鍵   
next()     指向下一個元素的鍵   

next()     指向下一個元素

生成器是PHP 5.5 引入的新特性,但是目前貌似很少人用到它。

下面試PHP 官方文件上對生成器的解釋:

生成器提供了一種更容易的方法來實現簡單的物件迭代,相比較定義類別實作Iterator 介面的方式,效能開銷和複雜性大大降低。

產生器允許你在 foreach 程式碼區塊中寫程式碼來迭代一組資料而不需要在記憶體中建立一個陣列, 那會使你的記憶體達到上限,或會佔據可觀的處理時間。

相反,你可以寫一個生成器函數,就像一個普通的自定義函數一樣, 和普通函數只返回一次不同的是, 生成器可以根據需要yield 多次,以便生成需要迭代的值。

為了體現生成器的有點,下面我們定義一個函數來進行比較:

function func1()
{
    foreach (range(0, 1000000) as $value){
        echo $value;
    }
}

func1();
// ( ! ) Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 402653192 bytes) in xxx.php on line 5
登入後複製
因為創建如此大的數組到內存中進行迭代,則PHP 直接提示超出了單個進程的內存限制。

下面我們換做生成器的方式來處理:

function func1()
{
    foreach (range(0, 1000000) as $value){
        yield $value;
    }
}

var_dump(func1()); // object(Generator)[1]
foreach (func1() as $value){
    echo $value;
}
登入後複製
可以看到我們呼叫func1() 回傳了一個Generator 對象,這個物件可以使用foreach 迭代,每次迭代,PHP會要求Generator 實例計算並提供下一個要迭代的值。

生成器的優雅體現在每次產出一個值之後,生成器的內部狀態都會停頓;

向生成器請求下一個值時,內部狀態又會恢復。生成器內部的狀態會一直在停頓和復原之間切換,直到抵達函數定義體的末端或遇到空的return語句為止。

【推薦學習:PHP影片教學

####

以上是實例講解PHP裡的Iterator和Generator的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:segmentfault.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板