Is iterable: примеры (PHP)

Функция is_iterable в PHP: полный обзор с примерами
Раздел: Работа с переменными
is_iterable(mixed $value): bool
Основные сведения о функции is_iterable

Функция is_iterable() проверяет, является ли переданное значение итерируемым, то есть таким, по которому можно пройтись с помощью конструкции foreach. Она была введена в PHP 7.1.

Функция используется в ситуациях, когда код должен работать с данными, которые могут быть представлены в разных форматах: массивами, объектами, реализующими интерфейс Traversable, или генераторами. Это упрощает проверку перед началом цикла.

Аргументы функции

Функция принимает один обязательный аргумент:
mixed $value — проверяемое значение. Может быть любого типа.

Функция возвращает true, если $value является массивом, объектом, реализующим Traversable, или генератором. В противном случае возвращает false.

Базовые примеры использования
Проверка массива
$arr = [1, 2, 3];
var_dump(is_iterable($arr));
bool(true)
Проверка объекта с Traversable
$obj = new ArrayIterator(['a', 'b', 'c']);
var_dump(is_iterable($obj));
bool(true)
Проверка генератора
function gen() { yield 1; }
$generator = gen();
var_dump(is_iterable($generator));
bool(true)
Проверка скалярных значений
var_dump(is_iterable(123));
var_dump(is_iterable('строка'));
var_dump(is_iterable(null));
bool(false)
bool(false)
bool(false)
Проверка простого объекта
$std = new stdClass();
var_dump(is_iterable($std));
bool(false)
Похожие функции в PHP

В PHP существуют другие функции для проверки типа данных, которые могут быть использованы в похожих контекстах.

Проверяет, является ли переменная массивом. is_iterable() шире, так как принимает и объекты с Traversable.

instanceof Traversable

Проверка с помощью оператора instanceof позволяет определить, реализует ли объект интерфейс Traversable (который реализуют Iterator и IteratorAggregate). Однако этот способ не сработает для массивов и генераторов.

$obj = new ArrayIterator([]);
$check = ($obj instanceof Traversable); // true
$check2 = ([] instanceof Traversable); // Ошибка
Выбор функции

is_iterable() предпочтительнее, когда нужна универсальная проверка для передачи в foreach. is_array() используется, когда важна именно массивная структура. instanceof Traversable применяется для строгой проверки объектов-итераторов.

Типичные ошибки
Ожидание, что объект stdClass является итерируемым

Объекты класса stdClass по умолчанию не реализуют Traversable.

$data = (object) ['a' => 1];
if (is_iterable($data)) {
    foreach ($data as $v) { /* этот блок не выполнится */ }
}
echo 'Объект stdClass не прошел проверку is_iterable.';
Объект stdClass не прошел проверку is_iterable.
Путаница с is_iterable и is_countable

Функция is_countable() проверяет, что по значению можно пройти функцией count(). Не все итерируемые значения являются countable (например, генераторы).

function gen() { yield 1; }
$g = gen();
var_dump(is_iterable($g)); // true
var_dump(is_countable($g)); // false
bool(true)
bool(false)
История изменений

Функция is_iterable() была добавлена в PHP 7.1. В PHP 8.0 и позднее ее поведение не изменялось. Добавление функции было логичным шагом для замены распространенной, но неудобной проверки is_array($var) || $var instanceof Traversable.

Расширенные примеры
Использование в функции для безопасного перебора
Пример php
function processIterable(iterable $items) {
    foreach ($items as $item) {
        echo $item . "\n";
    }
}

// Проверка перед вызовом функции, требующей iterable
$potentialData = getDataFromSource(); // Может вернуть разное
if (is_iterable($potentialData)) {
    processIterable($potentialData);
} else {
    echo 'Данные для обработки не итерируемы.';
}

// Пример возврата из getDataFromSource
function getDataFromSource() {
    // Может вернуть массив...
    // return ['A', 'B'];
    // ... или объект-итератор...
    // return new ArrayIterator(['X', 'Y']);
    // ... или что-то еще.
    return 'просто строка';
}
Данные для обработки не итерируемы.
Проверка с типом iterable в объявлении

В PHP 7.1+ можно использовать iterable как тип параметра или возвращаемого значения. Функция is_iterable() полезна для внутренних проверок, когда тип не строгий.

Пример php
function handleData(iterable $data): void {
    // Здесь $data гарантированно итерируема.
    var_dump('Приняты итерируемые данные', is_iterable($data));
}

handleData([1,2]); // Работает
// handleData(123); // Вызовет TypeError
string(47) "Приняты итерируемые данные"
bool(true)
Работа с объектами, реализующими IteratorAggregate
Пример php
class MyCollection implements IteratorAggregate {
    private $items = [];
    public function add($item) { $this->items[] = $item; }
    public function getIterator(): Traversable {
        return new ArrayIterator($this->items);
    }
}

$collection = new MyCollection();
$collection->add('Первый');
$collection->add('Второй');

var_dump(is_iterable($collection));
foreach ($collection as $item) {
    echo $item . " ";
}
bool(true)
Первый Второй
Отличие от проверки через is_array || instanceof Traversable
Пример php
$generator = (function() { yield from []; })();

// Старый способ
$oldCheck = (is_array($generator) || $generator instanceof Traversable);
var_dump($oldCheck);

// Новый способ
$newCheck = is_iterable($generator);
var_dump($newCheck);
bool(true)
bool(true)

Хотя результат одинаков, is_iterable() короче и понятнее, а также корректно работает с генераторами, которые являются объектами, реализующими Traversable.

Аналоги в других языках

Is iterable в Python

В Python используется функция iter() в сочетании с обработкой исключения TypeError или абстрактный базовый класс collections.abc.Iterable.

from collections.abc import Iterable
print(isinstance([1,2], Iterable))  # True
print(isinstance(123, Iterable))    # False

Is iterable в Javascript

В JavaScript проверка на итерируемость часто заключается в проверке наличия метода [Symbol.iterator]. Универсальной встроенной функции для этого нет.

function isIterable(obj) {
    return obj != null && typeof obj[Symbol.iterator] === 'function';
}
console.log(isIterable([1,2])); // true
console.log(isIterable({}));    // false

Is iterable в MySQL

Прямого аналога в SQL нет, так как это язык запросов, а не императивного программирования. Концепция итерирования применяется на уровне обработки результирующих наборов в коде приложения.

PHP is_iterable function comments

En
Is iterable Verify that the contents of a variable is an iterable value