is_iterable()用于判断变量是否可被foreach安全遍历,适用于函数参数校验、配置预检等场景;它返回true的对象包括数组、Traversable实例和生成器,但不包括字符串和null。

is_iterable() 的适用场景和基本用法
判断一个变量能否被 foreach 安全遍历,就用 is_iterable()。它不是用来“查是不是数组”的替代品,而是统一处理「数组 or Traversable 对象(含生成器)」的可遍历性校验。
典型使用位置:函数入口参数校验、配置项结构预检、API 返回数据类型兜底。
-
is_iterable([1, 2, 3])→ true -
is_iterable(new ArrayIterator([1]))→ true -
is_iterable((function() { yield 1; })())→ true -
is_iterable("hello")→ false(字符串不被视为 iterable 类型) -
is_iterable(null)→ false
为什么不能用 is_iterable() 判断“是不是数组”
因为它的设计目标是「是否可遍历」,不是「是否为数组」。数组只是 iterable 的一种,is_iterable() 对 ArrayIterator、Generator、自定义 IteratorAggregate 类都返回 true,但你显然不能把它们当数组用(比如调 array_merge() 或 count() 前不加保护)。
如果你真正需要区分数组和其他可遍历结构:
立即学习“PHP免费学习笔记(深入)”;
- 检查数组 → 用
is_array() - 检查生成器 → 用
is_object($var) && $var instanceof \Generator - 检查任意 Traversable 对象(不含数组)→
!is_array($var) && $var instanceof \Traversable
PHP 版本兼容与降级写法
is_iterable() 是 PHP 7.1+ 原生函数,低于该版本会报 Call to undefined function is_iterable() 错误。
安全的兼容写法(推荐直接复制使用):
if (!function_exists('is_iterable')) {
function is_iterable($var): bool {
return is_array($var) || ($var instanceof \Traversable);
}
}
注意两点:
- 必须先
is_object()再instanceof?不用。instanceof \Traversable对非对象自动返回 false,无需额外防护 - 别写成
is_object($var) && $var instanceof \Traversable—— 这会漏掉数组,违背is_iterable()本意
常见误用和容易踩的坑
最典型的错误是拿 is_iterable() 当「万能类型守门员」用,结果在后续逻辑里假设它是数组或生成器,引发运行时错误。
例如:
$data = new ArrayObject([1, 2, 3]);
if (is_iterable($data)) {
$len = count($data); // ✅ OK,ArrayObject 支持 count()
$first = reset($data); // ✅ OK
} else {
throw new InvalidArgumentException();
}
但换成这个就崩了:
$data = (function() { yield 'a'; })();
if (is_iterable($data)) {
$len = count($data); // ❌ Warning: count(): Parameter must be an array or an object that implements Countable
}
所以关键点始终是:「可遍历」不等于「可计数」或「可随机访问」。真正要操作前,还得按实际类型做二次判断。



















