Предыстория: я делаю некий обработчик, и на входных данных я получаю обычный массив, следующего формата:
$data = ['guid', 'inp', 'outx', 'dcfoaf'];
(элементы этого массива - скажем так, некие ключи доступа)
Итак, ближе к теме, у меня есть другие данные, которые я обрабатываю через цикл foreach, и, в процессе выполнения этого цикла, у меня есть переменная (к примеру $xkey), в которой случайно выбирается один из ключей массива $data с помощью функции array_rand.
Но я подумал, возможно ли сделать так, чтобы во время обработки моего цикла, с каждой итерацией элемент массива $data выводился по порядку? Например:
Первая итерация цикла foreach (в переменной $xkey должно быть значение guid)
Вторая итерация цикла foreach (в переменной $xkey должно быть значение inp)
И тому подобное
Но, в чем сложность самого вопроса решения этой задачи, нужно это сделать так, чтобы (когда элементы массива $data заканчиваются) они вызывались в очередной раз сначала. На пятой итерации в переменной $xkey должно быть значение guid, а на шестой inp.
Спустя время, я нашел материал про генераторы в PHP, в котором я увидел оператор yield, там было написано следующее:
Вся суть генератора заключается в ключевом слове yield. В самом простом варианте оператор "yield" можно рассматривать как оператор "return", за исключением того, что вместо прекращения работы функции, "yield" только приостанавливает ее выполнение и возвращает текущее значение, и при следующем вызове функции она возобновит выполнения с места, на котором прервалась.
Я так и не разобрался как можно реализовать решение задачи с помощью этого, прошу помочь с реализацией (на простых примерах тоже приветствуется), и возможна ли она вообще? Жду любой помощи, спасибо!
Достаточно воспользоваться штатным InfiniteIterator, доступным уже очень давно, с PHP 5.1.0
$data = ['guid', 'inp', 'outx', 'dcfoaf'];
// вот и весь фокус:
$infinite = new InfiniteIterator(new ArrayIterator($data));
$i = 0;
foreach ($infinite as $xkey) {
echo '$xkey = '.$xkey.PHP_EOL;
if (++$i > 30) break; // чтобы хоть когда-нибудь прерваться
}
Можно и через генератором воспользоваться:
$data = ['guid', 'inp', 'outx', 'dcfoaf'];
$infinite = function($input) {
while (true) {
yield from $input;
}
};
$i = 0;
foreach ($infinite($data) as $xkey) {
echo '$xkey = '.$xkey.PHP_EOL;
if (++$i > 30) break;
}
А в принципе и PHP4 достаточно с указателем на элемент массива:
$data = ['guid', 'inp', 'outx', 'dcfoaf'];
$i = 0;
$xkey = current($data); // получаем первый элемент
while (true) {
echo '$xkey = '.$xkey.PHP_EOL;
if (++$i > 30) break;
$xkey = next($data);
if ($xkey === false) {
// следующего нет, берём вновь начало
$xkey = reset($data);
}
}
как еще один вариант решения без итераторов, уже упомянутый мною в комментарии, но обернутый в желаемую форму последовательного вызова функций:
$data = ['guid', 'inp', 'outx', 'dcfoaf'];
function demark(){
static $i = 0;
global $data;
return $data[ $i++ % count($data)];
}
echo demark();
echo demark();
echo demark();
echo demark();
echo demark();
echo demark();
echo demark();
Сборка персонального компьютера от Artline: умный выбор для современных пользователей