【PHP8.x】Generator::current()メソッドの使い方
currentメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
currentメソッドは、ジェネレータが現在一時停止している位置で生成された値を取得するメソッドです。PHPのジェネレータは、yieldキーワードを使用して値を一時的に生成し、処理を一時停止させることで、メモリを効率的に利用しながら繰り返し処理を行うための機能を提供します。このcurrentメソッドは、ジェネレータがyield式を通じて生成した現在の値を参照するために用いられます。
ジェネレータ関数が呼び出され、最初のyield式が実行されて値が生成された後、またはnext()メソッドによって次の値へと進んだ後にcurrent()メソッドを呼び出すことで、その時点での最新の生成値を取得することができます。例えば、ジェネレータがyield 20という式で値を生成した場合、current()は整数20を返します。
しかし、ジェネレータがまだ一度も値を生成していない状態や、すべての値の生成が完了しジェネレータが既に終了している場合には、current()メソッドはnullを返します。このメソッドは、ジェネレータオブジェクトの内部状態を把握し、現在どの値に注目しているかを確認する際に役立ちます。
構文(syntax)
1<?php 2 3function myGenerator() { 4 yield 'Hello'; 5 yield 'World'; 6} 7 8$generator = myGenerator(); 9echo $generator->current(); 10
引数(parameters)
引数なし
引数はありません
戻り値(return)
mixed
現在のイテレータ位置にある値を返します。イテレータが空の場合は null が返されます。
サンプルコード
PHP Generator::current() で値を取得する
1<?php 2 3/** 4 * Generator::current() の使用例 5 */ 6 7function numberGenerator(int $start, int $end): Generator 8{ 9 for ($i = $start; $i <= $end; $i++) { 10 yield $i; 11 } 12} 13 14$generator = numberGenerator(1, 3); 15 16// ジェネレータの現在の値を表示する 17echo $generator->current() . PHP_EOL; // 出力: 1 18 19$generator->next(); 20 21// ジェネレータの次の値を表示する 22echo $generator->current() . PHP_EOL; // 出力: 2 23 24$generator->next(); 25 26// ジェネレータの次の値を表示する 27echo $generator->current() . PHP_EOL; // 出力: 3 28 29$generator->next(); 30 31// ジェネレータが完了した場合、current() は値を返さない 32var_dump($generator->current()); // 出力: bool(false)
PHP 8における Generator クラスの current() メソッドは、ジェネレータが現在指している値を返します。引数は必要ありません。戻り値は、ジェネレータが生成する値の型に応じて mixed 型となります。
このサンプルコードでは、numberGenerator というジェネレータ関数を定義しています。この関数は、指定された開始値から終了値までの数値を順番に生成します。
$generator = numberGenerator(1, 3); でジェネレータオブジェクトを作成し、$generator->current() を呼び出すことで、ジェネレータが最初に指している値(この場合は 1)を取得して表示しています。
$generator->next(); を呼び出すことで、ジェネレータの内部ポインタを次の値に進めます。その後、再度 $generator->current() を呼び出すと、次の値(この場合は 2、3)が表示されます。
ジェネレータがすべての値を生成し終えた後、つまり next() を呼び出してジェネレータが完了状態になった場合、current() は false を返します。var_dump($generator->current()); の出力結果から、この挙動を確認できます。
current() メソッドは、ジェネレータが現在どの値を生成しているかを確認する際に使用します。ジェネレータの内部ポインタを進める next() メソッドと組み合わせて使用することで、順番に値を処理できます。
Generator::current()は、ジェネレータが現在指している値を返します。ジェネレータを最初に作成した直後は、next()を一度も呼ばれていないため、最初のyieldの値が返されます。next()を呼ぶごとに、ジェネレータの内部ポインタが進み、current()は次の値を返すようになります。ジェネレータが最後まで到達し、それ以上yieldする値がない場合、current()はfalseを返します。このfalseはジェネレータが完了したことを示すため、値がfalseになる可能性も考慮した上で利用する必要があります。current()を呼ぶ前にnext()を呼ぶ必要がある点に注意してください。
PHP Generator::currentで月の日付を取得する
1<?php 2 3/** 4 * 指定された年月の最終日を返す関数。 5 * 6 * @param int $year 年。 7 * @param int $month 月。 8 * @return int 指定された年月の最終日。 9 */ 10function getLastDayOfMonth(int $year, int $month): int 11{ 12 return (int)date('t', mktime(0, 0, 0, $month, 1, $year)); 13} 14 15/** 16 * 指定された年月の日付を生成する Generator 関数。 17 * 18 * @param int $year 年。 19 * @param int $month 月。 20 * @return Generator 日付を順番に返す Generator。 21 */ 22function generateDatesOfMonth(int $year, int $month): Generator 23{ 24 $lastDay = getLastDayOfMonth($year, $month); 25 26 for ($day = 1; $day <= $lastDay; $day++) { 27 yield new DateTimeImmutable("$year-$month-$day"); 28 } 29} 30 31// 使用例:2024年1月の日付を順番に表示する 32$year = 2024; 33$month = 1; 34 35$dateGenerator = generateDatesOfMonth($year, $month); 36 37foreach ($dateGenerator as $date) { 38 echo $date->format('Y-m-d') . PHP_EOL; 39} 40 41// current() メソッドの使用例 (foreach ループ内で暗黙的に使われるため、ここでは直接的な使用例を示す) 42$dateGenerator->rewind(); // ジェネレータを初期位置に戻す 43$firstDate = $dateGenerator->current(); 44if ($firstDate instanceof DateTimeImmutable) { 45 echo "最初の日: " . $firstDate->format('Y-m-d') . PHP_EOL; 46} else { 47 echo "ジェネレータが空です。" . PHP_EOL; 48} 49
PHP 8のGeneratorクラスにおけるcurrentメソッドについて解説します。currentメソッドは、ジェネレータが現在指している値を返します。ジェネレータは、yieldキーワードを使って値を順番に生成する特別な関数です。
サンプルコードでは、指定された年月の全ての日付をDateTimeImmutableオブジェクトとして生成するgenerateDatesOfMonth関数を定義しています。この関数は、yieldを使って日付を一つずつ返します。
ジェネレータから値を取り出すには、通常foreachループを使用します。foreachループは、内部で自動的にジェネレータのcurrentメソッドを呼び出し、現在の値を処理します。
サンプルコードの後半部分では、currentメソッドを直接使用する例を示しています。まず、rewindメソッドでジェネレータを初期位置に戻しています。これは、ジェネレータが既に最後まで進んでいる場合に、最初の要素から再度アクセスできるようにするためです。その後、$dateGenerator->current()を呼び出すことで、ジェネレータが指す最初のDateTimeImmutableオブジェクトを取得し、フォーマットして表示しています。
currentメソッドは引数を取りません。戻り値はmixed型であり、ジェネレータが現在指している値を返します。ジェネレータが空の場合や、rewindやnextで終端を超えた場合にはNULLを返します。currentメソッドを使用することで、ジェネレータの現在の状態を直接的に確認することができます。foreach文で暗黙的に使用されることが多いですが、ジェネレータの状態を細かく制御したい場合に役立ちます。
Generatorクラスのcurrent()メソッドは、ジェネレータが現在指している値を返します。foreachループでは自動的に呼び出されるため、意識することは少ないかもしれません。ジェネレータは一度値をyieldすると、その位置を保持します。そのため、再度同じ値を参照するには、rewind()でジェネレータを初期位置に戻す必要があります。current()を呼び出す前にrewind()を忘れると、意図しない値が返ってくる可能性があります。また、ジェネレータが空の場合、current()はNULLを返すことがあります。そのため、返り値が期待する型(この例ではDateTimeImmutable)であるかを確認することが重要です。型チェックを怠ると、後続の処理でエラーが発生する可能性があります。
PHP Generator::current()で現在の値を取得する
1<?php 2 3/** 4 * PHPのGenerator::current()メソッドの基本的な使い方を示すサンプルコードです。 5 * ジェネレータ関数がyieldした現在の値を取得するために使用されます。 6 * 7 * システムエンジニアを目指す初心者の方にも理解しやすいように、 8 * ジェネレータのライフサイクルとcurrent()の役割を簡潔に示します。 9 */ 10 11/** 12 * 簡単な整数のシーケンスを生成するジェネレータ関数です。 13 * yieldキーワードを使って値を順次生成し、メモリ効率を高めます。 14 * 15 * @return Generator 生成された値を順次返すGeneratorオブジェクト 16 */ 17function generateSimpleNumbers(): Generator 18{ 19 echo "DEBUG: 'generateSimpleNumbers' 開始" . PHP_EOL; 20 yield 100; // 最初の値 21 echo "DEBUG: 100をyieldしました" . PHP_EOL; 22 yield 200; // 2番目の値 23 echo "DEBUG: 200をyieldしました" . PHP_EOL; 24 yield 300; // 3番目の値 25 echo "DEBUG: 300をyieldしました" . PHP_EOL; 26 echo "DEBUG: 'generateSimpleNumbers' 終了" . PHP_EOL; 27} 28 29// ---------------------------------------------------- 30// ジェネレータの使用例 31// ---------------------------------------------------- 32 33// 1. ジェネレータ関数を呼び出してGeneratorオブジェクトを取得します。 34// この時点では、ジェネレータ関数の内部のコードはまだ実行されていません。 35$generator = generateSimpleNumbers(); 36 37echo "--- ジェネレータの処理開始 ---" . PHP_EOL; 38 39// 2. ジェネレータが有効な間(つまり、まだyieldすべき値がある間)ループします。 40while ($generator->valid()) { 41 // Generator::current() メソッドを使用して、 42 // ジェネレータが現在指している(最後にyieldされた)値を取得します。 43 // このメソッドは、ジェネレータが現在一時停止している場所の値を返します。 44 echo "現在の値: " . $generator->current() . PHP_EOL; 45 46 // Generator::next() メソッドを呼び出して、 47 // ジェネレータの実行を再開し、次のyieldステートメントまで進めます。 48 // 次のcurrent()呼び出しでは、新しい値が取得されます。 49 $generator->next(); 50} 51 52echo "--- ジェネレータの処理完了 ---" . PHP_EOL; 53 54// ジェネレータが終了した後 (valid() が false になった後) に current() を呼び出すと、 55// ジェネレータが指す要素がもう存在しないため、null が返されます。 56echo "ジェネレータ終了後の current() の値: " . var_export($generator->current(), true) . PHP_EOL; 57 58?>
PHP 8のGeneratorクラスに属するcurrent()メソッドは、ジェネレータ関数がyieldキーワードを使って一時停止し、値を生成している際に、その「現在の」値を引数なしで取得するために使用されます。このメソッドは、ジェネレータが現在指している要素の値を返し、ジェネレータの実行を再開することはありません。
戻り値はmixed型で、ジェネレータがyieldする値の型によって整数や文字列など様々です。サンプルコードでは、generateSimpleNumbers()関数が生成する100、200、300といった整数値を、whileループ内で$generator->current()を呼び出すことで順に取得しています。current()で現在の値を取得した後、$generator->next()を呼び出すことで、ジェネレータは次のyieldステートメントまで実行を再開し、次のcurrent()呼び出しで新しい値が得られるようになります。ジェネレータがまだ開始されていない段階や、すべての値の生成を終えて終了した後にcurrent()を呼び出した場合、戻り値はnullとなります。
Generator::current()メソッドは、ジェネレータが現在一時停止している場所の値を返しますが、ジェネレータの実行を次に進める役割はありません。そのため、通常はGenerator::next()メソッドと組み合わせて使用し、次の値を生成するように指示する必要があります。ジェネレータ関数を呼び出した時点では、内部の処理はまだ実行されていません。実際にコードが実行されるのは、最初にcurrent()やnext()が呼び出された時です。ジェネレータが全ての値をyieldし終え、valid()がfalseになった後にcurrent()を呼び出すと、nullが返されます。これはエラーではなく、生成すべき値がもうないことを示します。ジェネレータは大量のデータを扱う際にメモリ使用量を抑えられるため、パフォーマンスが重要な場面で非常に有用です。
PHP Generator::current() でタイムスタンプを生成する
1<?php 2 3/** 4 * 指定された回数だけ現在のUnixタイムスタンプを生成するジェネレータ。 5 * 各タイムスタンプの生成間に1秒間待機し、異なる値になることを保証します。 6 * 7 * @param int $count 生成するタイムスタンプの数 8 * @return Generator 生成されたタイムスタンプを含むGeneratorオブジェクト 9 */ 10function generateTimestamps(int $count): Generator 11{ 12 for ($i = 0; $i < $count; $i++) { 13 // 現在のUnixタイムスタンプを生成してyieldする 14 yield time(); 15 // 最後の要素の生成後には待機しない 16 if ($i < $count - 1) { 17 sleep(1); 18 } 19 } 20} 21 22// ジェネレータオブジェクトを作成 23$timestampGenerator = generateTimestamps(3); 24 25echo "--- Generator::current() を使った手動イテレーションの例 ---\n"; 26 27// Generator::current() は、ジェネレータが現在指し示している要素の値を返します。 28// ジェネレータは初期状態で最初の要素を指しています。 29echo "ジェネレータの初期状態(最初の要素):" . $timestampGenerator->current() . "\n"; 30 31// Generator::next() を呼び出すと、ジェネレータは次の要素に進みます。 32$timestampGenerator->next(); 33echo "next() 呼び出し後(次の要素):" . $timestampGenerator->current() . "\n"; 34 35// もう一度 Generator::next() を呼び出します。 36$timestampGenerator->next(); 37echo "さらに next() 呼び出し後(次の要素):" . $timestampGenerator->current() . "\n"; 38 39// 全ての要素を消費した後、さらに next() を呼び出すとジェネレータは終了状態になります。 40// この場合、current() は null を返します。 41$timestampGenerator->next(); 42echo "全ての要素を消費した後:" . var_export($timestampGenerator->current(), true) . "\n"; 43 44echo "\n--- foreach ループでの Generator の一般的な利用例 ---\n"; 45// 通常、ジェネレータは foreach ループで使用され、 46// Generator::current() や Generator::next() は PHP によって内部的に呼び出されます。 47$anotherTimestampGenerator = generateTimestamps(2); // 新しいジェネレータインスタンスを作成 48foreach ($anotherTimestampGenerator as $key => $timestamp) { 49 echo "キー: $key, 生成されたタイムスタンプ: $timestamp\n"; 50}
PHP 8 の Generator クラスが提供する current() メソッドは、ジェネレータが現在一時停止し、yield キーワードによって生成された値を取得するために使用されます。このメソッドは引数を取らず、yield された値がどのような型であっても対応できるよう、mixed 型の値を戻り値として返します。
サンプルコードでは、generateTimestamps 関数がUnixタイムスタンプを生成するジェネレータとして定義されています。$timestampGenerator = generateTimestamps(3); でジェネレータオブジェクトを作成した後、$timestampGenerator->current() を初めて呼び出すと、ジェネレータは実行を開始し、最初の yield time() の値を返します。
その後、$timestampGenerator->next() メソッドを呼び出すことで、ジェネレータは次の yield 文まで処理を進めます。再度 current() を呼び出すと、新しく yield された値が取得できます。全ての要素を生成し終えてジェネレータが完了状態になると、current() メソッドは null を返します。
通常、ジェネレータは foreach ループで利用され、PHPが内部的に current() や next() を自動的に呼び出して要素を順番に処理します。current() メソッドは、このようにジェネレータの要素を手動で取得し、イテレーションの進行を制御したい場合に特に役立ちます。
Generator::current()は、ジェネレータが現在指し示している要素の値を返すだけで、ジェネレータ自体を進めません。次の要素に進むには、必ずGenerator::next()を呼び出す必要があります。全ての要素を消費し終えた後でcurrent()を呼び出すとnullが返されるため、その場合の戻り値の処理に注意してください。通常、ジェネレータはforeachループで安全に利用され、current()やnext()はPHPが内部的に処理します。また、ジェネレータは一度イテレートすると状態を記憶するため、同じ要素を最初から再度取得したい場合は、新しいジェネレータオブジェクトを作成してください。