可迭代对象和数组类型提示?

2022-08-30 09:35:13

我有很多函数,它们要么具有数组的类型提示,要么用于检查变量的数组性。is_array()

现在我开始使用可迭代的对象。它们实现 或 。如果它们通过类型提示或经历,它们是否会被接受为数组?IteratorIteratorAggregateis_array()

如果我必须修改我的代码,是否有一种通用的,或者我必须做这样的事情:is_iterable()

if ( is_array($var) OR $var instance_of Iterable OR $var instanceof IteratorAggregate ) { ... }

还有哪些其他可迭代接口?


答案 1

我想你的意思是实例,PHP没有接口。不过,它确实有一个可遍历的界面。 并且两者都扩展(并且AFAIK是唯一这样做的人)。IteratorIterableIteratorIteratorAggregateTraversable

但是不,实现的对象不会通过检查,也没有内置函数。您可以使用的支票是Traversableis_array()is_iterable()

function is_iterable($var) {
    return (is_array($var) || $var instanceof Traversable);
}

需要明确的是,所有php对象都可以使用foreach进行迭代,但只有其中一些实现。因此,所呈现的函数不会检测 foreach 可以处理的所有事情。Traversableis_iterable


答案 2

PHP 7.1.0 引入了可迭代伪类型和 is_iterable() 函数,这是专门为此而设计的:

这[...]提出了一种新的伪类型。此类型类似于 接受多个类型而不是单个类型。iterablecallable

iterable接受任何 或 对象实现。这两种类型都是可迭代的,并且可以从生成器中使用。arrayTraversableforeachyield

function foo(iterable $iterable) {
    foreach ($iterable as $value) {
        // ...
    }
}

这 [...] 还添加了一个返回布尔值的函数:如果某个值是可迭代的,并且将被伪类型接受,则对于其他值。is_iterable()trueiterablefalse

var_dump(is_iterable([1, 2, 3])); // bool(true)
var_dump(is_iterable(new ArrayIterator([1, 2, 3]))); // bool(true)
var_dump(is_iterable((function () { yield 1; })())); // bool(true)
var_dump(is_iterable(1)); // bool(false)
var_dump(is_iterable(new stdClass())); // bool(false)

推荐