首頁  >  文章  >  後端開發  >  PHP 迭代器 生成器的介紹

PHP 迭代器 生成器的介紹

不言
不言原創
2018-07-05 15:08:271752瀏覽

這篇文章主要介紹了關於PHP 迭代器產生器的介紹,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

迭代和迭代器

迭代是指重複執行一個過程,每執行一次叫做迭代一次。例如普通的遍歷便是迭代:

$arr = [1, 2, 3, 4, 5];foreach($arr as $key => $value) {    echo $key . ' => ' . $value . "\n";}

我們可以看到透過foreach對數組遍歷並迭代輸出其內容。在foreach內部,每次迭代都會將目前的元素的值賦給$value並將陣列的指標移動指向下一個元素為下一次迭代做準備,從而實現順序遍歷。像這樣能夠讓外部的函數迭代自己內部資料的介面就是迭代器介面,對應的那個被迭代的自己就是迭代器物件

PHP提供了統一的迭代器介面:

Iterator extends Traversable {    // 返回当前的元素
    abstract public mixed current(void)
    // 返回当前元素的键
    abstract public scalar key(void)
    // 向下移动到下一个元素
    abstract public void next(void)
    // 返回到迭代器的第一个元素
    abstract public void rewind(void)
    // 检查当前位置是否有效
    abstract public boolean valid(void)}

透過實作Iterator介面,我們可以自行的決定如何遍歷物件。

foreach之所以能工作,是因為這些集合類別都實現了Iterable接口,該接口中定義了Iterator迭代器的產生方法,並且foreach就是通過Iterable接口在序列中進行移動。

yield和生成器

相比較迭代器,生成器提供了一種更容易的方法來實現簡單的物件迭代,效能開銷和複雜性都大大降低。

一個生成器函數看起來像一個普通的函數,不同的是普通函數返回一個值,而生成器可以yield產生許多個值,並且每一次的yield只是暫停目前的執行狀態,下次呼叫生成器函數時,PHP會從上次暫停的狀態繼續執行。

我們在使用生成器的時候可以像關聯數組那樣指定一個鍵名對應生成的值。如下產生一個鍵值對與定義一個關聯數組相似。

function xrange($start, $limit, $step = 1) {    
for ($i = $start, $j = 0; $i <= $limit; $i += $step, $j++) {        // 给予键值
        yield $j => $i;
    }
}$xrange = xrange(1, 10, 2);foreach ($xrange as $key => $value) {    
echo $key . &#39; => &#39; . $value . "\n";}

概念理解

先明確一個概念:產生器yield關鍵字不是回傳值,他的專業術語叫產出值,只是產生一個值。實際上生成器函數傳回的是一個Generator對象,這個物件不能透過new實例化,並且實作了Iterator介面。

那麼程式碼中 foreach 迴圈的是什麼? PHP使用生成器的時候,會回傳一個 Generator 類別的物件。 foreach 可以對此物件進行迭代,每一次迭代,PHP會透過 Generator 實例計算出下次需要迭代的值。這樣 foreach 就知道下次需要迭代的值了。

而且,在運作中 for 迴圈執行後,會立即停止。等待 foreach 下次迴圈時再來和  for  索要下次的值的時候,迴圈才會再執行一次,然後立即再次停止。直到不滿足條件不執行結束。

生成器優點

  • #產生器會對PHP應用的效能有非常大的影響

  • PHP程式碼運行時節省大量的記憶體

  • 比較適合計算大量的資料

實際開發應用程式:讀取超大文件

PHP開發很多時候都要讀取大文件,像是csv文件、text文件,或是一些日誌文件。這些文件如果很大,例如5個G。這時,直接一次把所有的內容讀到記憶體中計算不太現實。使用生成器讀取文件,第一次讀取了第一行,第二次讀取了第二行,以此類推,每次加載到內存中的文字只有一行,大大的減小了記憶體的使用。

<?php
header("content-type:text/html;charset=utf-8");
function readTxt()
{
    # code...
    $handle = fopen("./test.txt", &#39;rb&#39;);

    while (feof($handle)===false) {
        # code...
        yield fgets($handle);
    }

    fclose($handle);
}

foreach (readTxt() as $key => $value) {
    # code...
    echo $value.&#39;<br />&#39;;
}

以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP中文網!

相關推薦:

PHP使用Azure Storage Blob上傳檔案

php介面內curl請求其他介面的介紹

以上是PHP 迭代器 生成器的介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn