Генераторы
14 июля 2018
Генератор в PHP это функция, используемая для перебора значений. На каждом вызове функция сохраняет своё состояние, а возврат значения в режиме итераций осуществляется с помощью оператора yield
Особенности:
// Генератор для получения следующих дней
// @param int $count - количество дней
// @return string - строка с датой в формате 'ДД.ММ.ГГГГ' (например, 05.07.2018)
function gen_next_days($count)
{
if($count<1) yield; /* Если вызван пустой yield, то функция вернёт NULL */
$current_timestamp = time();
for($i=1; $i<=$count; $i++)
{
yield date('d.m.Y', $current_timestamp + ($i * 86400));
}
}
/*
Сегодня 14 июля 2018.
Следующий код выведет:
15.07.2018
16.07.2018
17.07.2018
*/
$count_days = 3;
foreach(gen_next_days($count_days) as $str_date)
{
echo $str_date.'<br>';
}
Возврат пары ключ-значение
Для возврата ключа и значения используется конструкция вида yield $key => $value;function gen_next_days($count)
{
if($count<1) yield;
$current_ts = time();
for($i=1; $i<=$count; $i++)
{
$ts = $current_ts + ($i * 86400);
$str = date('d.m.Y', $ts);
yield $str => $ts;
}
}
$count_days = 3;
foreach(gen_next_days($count_days) as $z => $v)
{
echo $z.' => '.$v.'<br>';
}
Использование return
Если используется оператор yield, то функция будет возвращать объект класса Generator. Начиная с версии PHP 7 генераторы могут возвращать значение через оператор return. Но так как генератор возвращает объект, то получать значения от return нужно с использованием метода getReturn (ссылка на документацию).Особенности:
- Оператор return завершит выполнение функции и итераций соответственно;
- Генератор должен выполнится, иначе при попытке вызова метода getReturn возникнет ошибка Fatal error: Uncaught Exception: Cannot get return value of a generator that hasn't returned
//Генератор обходит числа от 1 до $max
//Функция возвращает число $max
function gen_numbers($max)
{
for($i=1; $i<=$max; $i++) yield $i;
return $max;
}
$a = gen_numbers(3);
/*
Если вызвать echo $a->getReturn(), то возникнет ошибка:
Fatal error: Uncaught Exception: Cannot get return value of a generator that hasn't returned
Ошибка возникла из-за того, что итерации генератора не дошли до вызова оператора return
*/
//Запускаем обход генератора
foreach($a as $v) echo $v; /* Выведет 123 */
echo $a->getReturn(); /* Выведет 3 */
Отладка
Для отладки удобно использовать функцию iterator_to_array (ссылка на документацию), которая обходит итерации генератора и возвращает результирующий массивfunction gen_next_days($count)
{
if($count<1) yield;
$current_ts = time();
for($i=1; $i<=$count; $i++)
{
$ts = $current_ts + ($i * 86400);
$str = date('d.m.Y', $ts);
yield $str => $ts;
}
}
//Заносим результат итераций в массив
$a = iterator_to_array(gen_next_days(3));
echo '<pre>';
print_r($a);
echo '</pre>';
/*
В результате на выводе получим:
Array
(
[15.07.2018] => 1531602000
[16.07.2018] => 1531688400
[17.07.2018] => 1531774800
)