PHP入門:Generatorsについて -vol.2-

スポンサーリンク
PHP入門:Generatorsについて -vol.2- 用語解説
PHP入門:Generatorsについて -vol.2-
この記事は約6分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

今日は、PHPのGeneratorsについてご紹介します。

スポンサーリンク

背景

PHP8.2を利用したAPIを開発しているときにGeneratorsを利用したので、そのときの調査内容を備忘としてのこしました。

こちらのサイトを参考にしています。

ジェネレータの構文

ジェネレータ関数は通常の関数と似ていますが、値を返す代わりに、ジェネレータは必要なだけの値を「yield」します。yieldを含む任意の関数はジェネレータ関数となります。

ジェネレータ関数が呼び出されると、イテレーション可能なオブジェクトが返されます。そのオブジェクトを反復処理すると(例えば、foreachループを使用して)、PHPはオブジェクトのイテレーションメソッドを必要なたびに呼び出し、ジェネレータが値を返すときにその状態を保存します。次に値が必要なときに再開できるようにします。

もはや返す値がない場合、ジェネレータは単純に終了し、呼び出し元のコードは配列の値がなくなったかのように続行します。

注意:

ジェネレータは値を返すことができ、Generator::getReturn()を使用して取得できます。

yieldキーワード

ジェネレータ関数の中心にはyieldキーワードがあります。最も単純な形では、yield文はreturn文と似ていますが、関数の実行を停止して戻る代わりに、yieldはジェネレータをループしているコードに値を提供し、ジェネレータ関数の実行を一時停止します123

ジェネレータ関数は、必要なだけの値を生成するためにyieldを使用します。yieldを含む関数はジェネレータ関数となります。ジェネレータ関数が呼び出されると、イテレータ可能なオブジェクトが返され、そのオブジェクトを反復処理するときに必要な値を提供します。ジェネレータは値を生成するたびにその状態を一時的に保存し、次の値が必要なときに再開できるようにします。

yieldを使ったジェネレータは、大量のデータを効率的に処理する際や、リアルタイムでデータを生成する必要がある場合に特に有用です。

例1 yieldの簡単な例

<?php
function gen_one_to_three() {
    for ($i = 1; $i <= 3; $i++) {
        // Note that $i is preserved between yields.
        yield $i;
    }
}

$generator = gen_one_to_three();
foreach ($generator as $value) {
    echo "$value\n";
}

このコードは、PHPジェネレータを使用する例です。ジェネレータは、特定の条件で値を生成するための強力な機能です。

  1. ジェネレータ関数の定義:
    • gen_one_to_three というジェネレータ関数が定義されています。
    • この関数は、for ループを使用して、1から3までの整数を生成します。
    • yield $i; の部分で、$i の値をジェネレータに返します。
  2. ジェネレータの利用:
    • gen_one_to_three() を呼び出すと、ジェネレータオブジェクトが返されます。
    • foreach ループを使って、ジェネレータから値を取り出します。
    • 各値は $value に代入され、echo "$value\n"; で表示されます。
  3. 出力結果:
    • 上記のコードを実行すると、以下のような出力が得られます:
1
2
3

注意:

内部的には、連続した整数キーは、非連想配列と同様に、生成された値とペアになります。

キーを指定して値を生成する

PHPは連想配列もサポートしており、ジェネレータも同様です。上記の例で示したように、単純な値を生成するだけでなく、同時にキーを生成することもできます。

キーと値のペアを生成するための構文は、連想配列を定義する際に使用されるものと非常に似ています。以下にその例を示します。

サンプル1

<?php
function gen_key_value_pair() {
    yield 'apple' => 'red';
    yield 'banana' => 'yellow';
    yield 'grape' => 'purple';
}

$generator = gen_key_value_pair();
foreach ($generator as $fruit => $color) {
    echo "$fruit is $color.\n";
}

このコードを実行すると、以下の出力が得られます:

apple is red.
banana is yellow.
grape is purple.

サンプル2

<?php
/*
 * The input is semi-colon separated fields, with the first
 * field being an ID to use as a key.
 */

$input = <<<'EOF'
1;PHP;Likes dollar signs
2;Python;Likes whitespace
3;Ruby;Likes blocks
EOF;

function input_parser($input) {
    foreach (explode("\n", $input) as $line) {
        $fields = explode(';', $line);
        $id = array_shift($fields);

        yield $id => $fields;
    }
}

foreach (input_parser($input) as $id => $fields) {
    echo "$id:\n";
    echo "    $fields[0]\n";
    echo "    $fields[1]\n";
}

このコードは、PHPジェネレータを使用する例です。ジェネレータは、特定の条件で値を生成するための強力な機能です。

  1. ジェネレータ関数の定義:
    • input_parser というジェネレータ関数が定義されています。
    • この関数は、セミコロンで区切られたフィールドからなる入力文字列を受け取ります。
    • explode("\n", $input) で入力文字列を行ごとに分割し、各行のフィールドを取得します。
    • array_shift($fields) でフィールドの先頭の要素を取り出し、それをIDとして使用します。
    • yield $id => $fields; の部分で、IDとフィールドのペアをジェネレータに返します。
  2. ジェネレータの利用:
    • input_parser($input) を呼び出すと、ジェネレータオブジェクトが返されます。
    • foreach ループを使って、ジェネレータからIDとフィールドを取り出します。
    • 各IDとフィールドは $id$fields に代入され、それぞれ表示されます。
  3. 出力結果:
    • 上記のコードを実行すると、以下のような出力が得られます:
1:
    PHP
    Likes dollar signs
2:
    Python
    Likes whitespace
3:
    Ruby
    Likes blocks

おわりに

今日は、PHPのGeneratorsについてご紹介しました。

よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました