Longhorn PHP 2025 - Speakers and Schedule Announced!

Generator::rewind

(PHP 5 >= 5.5.0, PHP 7, PHP 8)

Generator::rewindイテレータを最初の yield まで巻き戻す

説明

public Generator::rewind(): void

このメソッドは ジェネレーターを最初の yield の前のポイントまで巻き戻します。 このメソッドがコールされた際に、 ジェネレーターが最初の yield 式に達していない場合、 巻き戻す前に最初の yield まで進めます。 ジェネレーターが既に二番目の yield の始点に達している場合は Exception がスローされます。

注意:

これは、foreach ループを開始する際に 最初に コールされるメソッドです。foreach ループが実行された 後に 実行されるのでは ありません

パラメータ

この関数にはパラメータはありません。

戻り値

値を返しません。

例1 Generator::rewind() の例

<?php

function generator(): Generator
{
echo
"I'm a generator!\n";

for (
$i = 1; $i <= 3; $i++) {
yield
$i;
}
}

// ジェネレータを初期化
$generator = generator();

// まだ達していない場合、最初の yield 式の開始までジェネレータを巻き戻します。
$generator->rewind(); // I'm a generator!

// ここでは何も起きません; ジェネレータは既に巻き戻されています。
$generator->rewind(); // No output (NULL)

// ここでは、まだ達していない場合、
// 最初の yield 式の開始までジェネレータを巻き戻します。
// そして、ジェネレータを反復します。
foreach ($generator as $value) {
// 最初の値を yield したあと、ジェネレータは
// 実行が再開されて次の yield に進むまで最初の
// yield 式にとどまったままです。
echo $value, PHP_EOL; // 1

break;
}

// 巻き戻しを再開します。
// エラーは発生しません。なぜんら、ジェネレータは最初の yield を越えて
// 進んでいないからです。
$generator->rewind();

echo
$generator->current(), PHP_EOL; // 1

// エラーは起きません。
// ジェネレータはまだ最初の yield に留まっています。
$generator->rewind();

// ここで、ジェネレータを二回目の yield 式に進めます。
$generator->next();

try {
// これは、例外をスローします。
// なぜなら、既にジェネレータが二回目の yield に進んでいるからです。
$generator->rewind(); // Fatal error: Uncaught Exception: Cannot rewind a generator that was already run
} catch (Exception $e) {
echo
$e->getMessage();
}

?>

上の例の出力は以下となります。

I'm a generator!
1
1
Cannot rewind a generator that was already run

add a note

User Contributed Notes 1 note

up
22
i&#39;m pati on stackoverflow
9 years ago
Actually, this method can be useful to test a generator before iterating, as it executes your function up to the first yield statement. I.e. if you try to read a non-existent file in a generator, an error will normally occur only in client code foreach()'s first iteration. Sometimes this can be critical to check beforehand.

Take a look at a modified example from here:
http://php.net/manual/ru/language.generators.overview.php#112985

<?php

function getLines($file) {
$f = fopen($file, 'r');
try {
while (
$line = fgets($f)) {
yield
$line;
}
} finally {
fclose($f);
}
}

$getLines = getLines('no_such_file.txt');
$getLines->rewind(); // with ->rewind(), a file read error will be thrown here and a log file will not be cleared

openAndClearLogFile();

foreach (
$getLines as $n => $line) { // without ->rewind(), the script will die here and your log file will be cleared
writeToLogFile('reading: ' . $line . "\n");
}

closeLogFile();

?>

P.S.: When you iterate over a generator after ->rewind(), you'll get the first yielded value immediately, as the preceding code was already executed.
To Top