m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

php5.5のジェネレータを少しだけ

これ見たほうが早いかも

サンプル1:yieldを指定する度にセーブして処理が戻る

sample
<?php
// きちんとfunctionで定義しないとダメらしい
function sample_generator(){
    $a = 0;
    yield $a;   // ここで戻る

    $a = 100;
    yield $a;   // ここで戻る

}
$g = sample_generator();

// foreachで繰り返ししてyield文の結果を返す
foreach($g as $item){
    var_dump($item);
}

※ジェネレータは関数を名前付きで定義しておかないと動かないよう

[vagrant@localhost php55]$ php sample1.php 
int(0)
int(100)
[vagrant@localhost php55]$ 

サンプル2:終了条件を呼び出し元で指定するまで繰り返す

sample2.php
<?php
// 定義
function sample_generator(){
    $i = 0;

    // こちらは無限ループ
    while(true){
        $i++;
        $msg = "";
        if($i % 3 == 0){
            $msg .= "Fizz";
        }
        if($i % 5 == 0){
            $msg .= "Buzz";
        }

        if($msg != ""){
            $msg = ":" . $msg;
        }

        yield $i . $msg;
    }
}

// 設定
$g = sample_generator();

// 処理
foreach($g as $item){

    // 呼び出し元で終了条件を指定
    if($item > 100){
        break;
    }
    var_dump($item);

}

[vagrant@localhost php55]$ php sample2.php 
string(1) "1"
string(1) "2"
string(6) "3:Fizz"
string(1) "4"
string(6) "5:Buzz"
string(6) "6:Fizz"
string(1) "7"
string(1) "8"
string(6) "9:Fizz"
string(7) "10:Buzz"
string(2) "11"
string(7) "12:Fizz"
string(2) "13"
string(2) "14"
string(11) "15:FizzBuzz"
string(2) "16"
string(2) "17"
string(7) "18:Fizz"
string(2) "19"
string(7) "20:Buzz"
string(7) "21:Fizz"
string(2) "22"
string(2) "23"
string(7) "24:Fizz"
string(7) "25:Buzz"
string(2) "26"
string(7) "27:Fizz"
string(2) "28"
string(2) "29"
string(11) "30:FizzBuzz"
string(2) "31"
string(2) "32"
string(7) "33:Fizz"
string(2) "34"
string(7) "35:Buzz"
string(7) "36:Fizz"
string(2) "37"
string(2) "38"
string(7) "39:Fizz"
string(7) "40:Buzz"
string(2) "41"
string(7) "42:Fizz"
string(2) "43"
string(2) "44"
string(11) "45:FizzBuzz"
string(2) "46"
string(2) "47"
string(7) "48:Fizz"
string(2) "49"
string(7) "50:Buzz"
string(7) "51:Fizz"
string(2) "52"
string(2) "53"
string(7) "54:Fizz"
string(7) "55:Buzz"
string(2) "56"
string(7) "57:Fizz"
string(2) "58"
string(2) "59"
string(11) "60:FizzBuzz"
string(2) "61"
string(2) "62"
string(7) "63:Fizz"
string(2) "64"
string(7) "65:Buzz"
string(7) "66:Fizz"
string(2) "67"
string(2) "68"
string(7) "69:Fizz"
string(7) "70:Buzz"
string(2) "71"
string(7) "72:Fizz"
string(2) "73"
string(2) "74"
string(11) "75:FizzBuzz"
string(2) "76"
string(2) "77"
string(7) "78:Fizz"
string(2) "79"
string(7) "80:Buzz"
string(7) "81:Fizz"
string(2) "82"
string(2) "83"
string(7) "84:Fizz"
string(7) "85:Buzz"
string(2) "86"
string(7) "87:Fizz"
string(2) "88"
string(2) "89"
string(11) "90:FizzBuzz"
string(2) "91"
string(2) "92"
string(7) "93:Fizz"
string(2) "94"
string(7) "95:Buzz"
string(7) "96:Fizz"
string(2) "97"
string(2) "98"
string(7) "99:Fizz"
string(8) "100:Buzz"
[vagrant@localhost php55]$

とまあこんな感じ
他にもファイル処理や配列のメモリ削減にも使えるようだけど今回はここまで

まとめ

ジェネレータ関数でシナリオを定義して、yieldでセーブ単位に呼び出して対応することが可能。
使い道がまだ、うまくつかめていないのでいろいろなソースを探して勉強していくしかないと思われる。

フレームワークとかだと共通部分とコンテンツでの呼び出しにyieldを使用する感じかな?
ファイルオープン処理とかは途中でcloseできないけどなんとか考えてみるしかない。