Итерируемые объекты в PHP
Итерируемый объект (iterable) в PHP — это любое значение, которое можно перебрать с помощью цикла foreach().
В PHP 7.1 был добавлен псевдотип iterable, который можно использовать для аргументов функций и возвращаемых значений.
Подходят значения двух видов: массивы и объекты, реализующие интерфейс Iterator.
PHP — использование iterable
Укажите iterable как тип параметра функции или как возвращаемый тип функции:
Пример
Функция, принимающая итерируемый параметр, вызывается один раз с массивом и один раз с объектом:
Вывод: PHP-скрипт
<?php
function printIterable(iterable $x) {
foreach($x as $item) {
echo $item;
}
}
// Вызов с массивом:
printIterable(["a", "b", "c"]);
// Вызов с объектом:
$iterator = new ArrayIterator(["d", "e", "f"]);
printIterable($iterator);
?>
Пример
Функция, возвращаемый тип которой — iterable:
Вывод: PHP-скрипт
<?php
function getIterable():iterable {
return ["a", "b", "c"];
}
foreach(getIterable() as $item) {
echo $item;
}
?>
PHP — создание итерируемых объектов
Любой массив является итерируемым, поэтому его можно передать в функцию, которая ожидает итерируемое значение.
То же относится и к объектам: любой объект, реализующий Iterator, также принимается.
Итератор хранит список элементов и предоставляет методы для перемещения по ним. Он держит указатель на одном элементе списка за раз, и у каждого элемента должен быть ключ, по которому его можно найти.
Ваш итератор должен определять эти пять методов:
current()— возвращает элемент под указателем, который может быть любого типа данныхkey()— возвращает ключ текущего элемента, который может быть только целым числом, числом с плавающей точкой, логическим значением или строкойnext()— перемещает указатель на один элемент вперёдrewind()— возвращает указатель на первый элементvalid()— возвращает true, пока внутренний указатель находится на элементе. Метод должен возвращать false, когда указатель не находится ни на каком элементе, например после вызоваnext()в конце списка
Пример
Здесь класс реализует Iterator, а его объект затем передаётся в функцию как итерируемое значение:
Вывод: PHP-скрипт
<?php
// Создаём итератор
class MyIterator implements Iterator {
private $items = [];
private $pointer = 0;
public function __construct($items) {
// array_values() гарантирует, что ключами будут числа
$this->items = array_values($items);
}
public function current() {
return $this->items[$this->pointer];
}
public function key() {
return $this->pointer;
}
public function next() {
$this->pointer++;
}
public function rewind() {
$this->pointer = 0;
}
public function valid() {
// count() показывает, сколько элементов в списке
return $this->pointer < count($this->items);
}
}
// Функция, которая работает с iterable
function printIterable(iterable $myIterable) {
foreach($myIterable as $item) {
echo $item;
}
}
// Используем итератор как iterable
$iterator = new MyIterator(["a", "b", "c"]);
printIterable($iterator);
?>