こんにちは!独学プログラマー&ライターのつぶらやです。
PHPでプログラムを書いていると、以下のように考える事があります。
配列を何度も呼び出すと負荷がかかる
何度も同じ関数を呼び出して処理の記述が複雑になる
今回はそんな悩みを解消するためにジェネレータという機能と、それを使用するためのyieldを以下の内容で紹介します。
ジェネレータを使って負荷を減らす
yieldの使い方【基本編】
yieldの使い方【応用編】
それではPHP5.5から導入されたジェネレータについて解説していきます。
ジェネレータを使うと負荷がかからない?
ジェネレータを使うと負荷を減らせる可能性があります。
ジェネレータとは
通常の関数はreturnで値を一度だけ値を返します。
ジェネレータを使用した関数は、yieldを記述する事で何度も値を保持出来ます。
配列の代わりにジェネレータ関数を作成してyieldで値を保持。
これがPHPのジェネレータ機能です。
具体的には次章のサンプルコードを見るとよく分かると思います。
ジェネレータを使うメリット
サンプルコードを説明する前に、ジェネレータを使用するとどういうメリットがあるかをお話します。
配列を作成する事なくforeachの処理をする場合、ジェネレータ関数で処理できるのでメモリの節約が出来る可能性があります。
また、複雑なプログラム記述を見やすく出来る場合もあるかと思います。
とても有意義な機能ですので、是非使い方をマスターして頂きたいです。
yieldの使い方【基本編】
ここからはサンプルコードを使って、通常の記述をジェネレータ関数で書き直して結果をみていきます。
<?php $array = [7, 4, 8]; foreach($array as $val) { echo $val; } ?>
結果 748
配列をforeachで回して、配列の値を返すプログラムです。
これをyieldを使ったジェネレータ関数に書き換えます。
<?php function yield_example() { $array = [7, 4, 8]; yield $array[0]; yield $array[1]; yield $array[2]; } foreach(yield_example() as $val) { echo $val; } ?>
結果 748
結果は通常の記述と同じになりました。
さて、基本のyieldの使い方はわかって頂けたかと思います。
しかし、前章で紹介したメリットについては当てはまっていないように思えますね。
実はこの章のサンプルは使い方をわかりやすくするためだけのもので、実際はこのような書き方はしません。
次章の応用編で詳しく説明します。
yieldの使い方【応用編】
前章のサンプルコードはyieldの説明をわかりやすくするためものでしたので、よく使う形に書き直してみます。
<?php function yield_example() { $array = [7, 4, 8]; for($i=0; $i<=2; $i++){ yield $array[$i]; } } foreach(yield_example() as $val) { echo $val; } ?>
配列の値を1つずつyieldしていた部分をforeach文で回す形にしました。
これでシンプルなコードになりました。
もう一つのメリット、負荷軽減の可能性についてはどうでしょうか。
今回のサンプルの場合は扱うデータは少ないので、ジェネレータを使用しても大した負荷対策にはならないと思います。
そこで新しい乱数発生させて、足していくコードを使って説明していきます。
<?php function example2($limit) { $array = []; for($i = 1; $i <= $limit; $i++) { $array[] = rand(1, 30); } return $array; // ※ここで配列を返す } $sum_value = 0; foreach(example2(5) as $value) { print($value."<br>"); $sum_value += $value; } ?>
コメントに書いてあるコメント部分で配列を返しています。
配列は発生した個数分メモリを使用します。
サンプルコードは配列の要素数が5つと少ないため問題ありませんが、何百万件と個数がある場合はどうでしょうか。
そこでジェネレータを使用するとメモリの節約が出来る可能性があるのです。
それでは、サンプルコードをyieldを使って修正します。
<?php function yield_example2($limit) { $array = []; for($i = 1; $i <= $limit; $i++) { yield rand(1, 30); } } $sum_value = 0; foreach(example2(5) as $value) { print($value."<br>"); $sum_value += $value; } ?>
結果は同じで、コードも殆ど変更がありません。
大量のデータを扱う場合などは特にジェネレータを使用したほうが良いです。
まとめ
本日はPHPのyield使い方について解説しました。
ジェネレータは使い方を覚えておくととても便利な機能です。
是非サンプルコードを動かしてマスターしてください。
それでは、また。