Generator::rewind

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

Generator::rewindПерематывает генератор к первому выражению yield

Описание

public Generator::rewind(): void

Метод перематывает генератор к первому выражению yield. При перемотке генератор выполнит код, который идёт перед первым выражением yield, если при вызове метода генератор ещё не дошёл до первого выражения yield. Метод выбросит исключение Exception, если метод вызывали, когда генератор уже перешёл ко второму выражению yield.

Замечание:

Это первый метод, который генератор автоматически вызывает при запуске цикла foreach. Метод не выполняется после цикла foreach.

Список параметров

У этой функции нет параметров.

Возвращаемые значения

Функция не возвращает значения после выполнения.

Примеры

Пример #1 Пример перемотки генератора методом Generator::rewind()

<?php

function generator(): Generator
{
echo
"Я генератор!\n";

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

// Инициализируем генератор
$generator = generator();

// Перематываем генератор к началу первого выражения yield,
// если генератор ещё не там
$generator->rewind(); // Я генератор!

// В этом месте ничего не произойдёт; генератор уже перемотался к первому yield
$generator->rewind(); // Ничего не выводит, возвращает NULL

// Цикл возвращает генератор к первому выражению yield,
// если генератор ещё не там, и начинает итерацию по генератору
foreach ($generator as $value) {
// После выдачи первого значения генератор остается
// на первом выражении yield, пока не возобновит выполнение и не продвинется к следующем yield
echo $value, PHP_EOL; // 1

break;
}

// Снова возобновляем работу генератора и «отматываем» к первому выражению yield.
// Слово «отматываем» в кавычках, потому что генератор уже на первом yield.
// Ошибка не возникает, поскольку генератор ещё не продвинулся дальше первого yield
$generator->rewind();

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

// Ошибка тоже не возникает, генератор всё ещё на первом выражении
$generator->rewind();

// Этот вызов продвигает генератор ко второму выражению yield
$generator->next();

try {
// Попытка перемотать генератор выбросит исключение Exception,
// потому что генератор уже перешёл ко второму выражению yield
$generator->rewind(); // Fatal error: Uncaught Exception: Cannot rewind a generator that was already run
} catch (Exception $e) {
echo
$e->getMessage();
}

?>

Результат выполнения приведённого примера:

Я генератор!
1
1
Cannot rewind a generator that was already run

Добавить

Примечания пользователей 1 note

up
22
i&#39;m pati on stackoverflow
8 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