如何检查变量是不是为数组?...或类似数组的东西
Posted
技术标签:
【中文标题】如何检查变量是不是为数组?...或类似数组的东西【英文标题】:How to check if variable is array?... or something array-like如何检查变量是否为数组?...或类似数组的东西 【发布时间】:2013-03-14 07:02:43 【问题描述】:我想使用带有变量的foreach
循环,但是这个变量可以是多种不同的类型,例如NULL
。
所以在foreach
之前我测试了一下:
if(is_array($var))
foreach($var as ...
但我意识到它也可以是一个实现Iterator
接口的类。也许我是盲人但是如何检查该类是否实现了接口?有类似is_a
函数或inherits
运算符的东西吗?我找到了class_implements
,我可以用,但也许有更简单的东西?
其次,更重要的是,我认为这个函数存在,足以检查变量is_array
或“实现Iterator
接口”还是我应该测试更多?
【问题讨论】:
if($var instanceof ArrayIterator) 是的,我很确定这是行不通的,甚至没有看过手册...... Iterable objects and array type hinting?的可能重复 【参考方案1】:<?php
$var = new ArrayIterator();
var_dump(is_array($var), ($var instanceof ArrayIterator));
返回bool(false)
或bool(true)
【讨论】:
【参考方案2】:您可以使用一个简单的函数检查Traversable
的实例。这适用于Iterator
的所有这些,因为Iterator extends Traversable
function canLoop($mixed)
return is_array($mixed) || $mixed instanceof Traversable ? true : false;
【讨论】:
"? true : false" 部分是多余的。 instanceof 已经给出了一个 bool 值作为结果。【参考方案3】:如果您在函数中使用foreach
,并且您期望一个数组或Traversable 对象,您可以键入提示该函数:
function myFunction(array $a)
function myFunction(Traversable)
如果您没有在函数中使用foreach
,或者您希望you can simply use this construct 都检查您是否可以迭代变量:
if (is_array($a) or ($a instanceof Traversable))
【讨论】:
谢谢。我希望这已经足够了,并且没有/不会有其他可以迭代的语言结构。 我发现is_array
很贵。计算成本似乎随着数组的大小而增加(这没有任何意义,因为它只是检查它是否是一个数组)。但它在图书馆里让我震惊地发生了。请参阅链接问题中的my comment。 instanceof Traversable
可以处理数组吗?我没有机会测试它的性能。
@ADTC AFAIR 数组是Traversable
的一个实例,所以是的。
@Shoe 我试过了here。 $var = array(1,2,3);
的结果是:is_array($var) = true
和 $var instanceof Traversable = false
。
@ADTC 是的,刚刚检查过。数组不实现Iterator
,因此不适用于Traversable
。【参考方案4】:
foreach
可以处理数组和对象。您可以通过以下方式检查:
$can_foreach = is_array($var) || is_object($var);
if ($can_foreach)
foreach ($var as ...
您不需要专门检查Traversable
,因为其他人在他们的答案中暗示了这一点,因为所有对象(如所有数组)都可以在 PHP 中遍历。
从技术上讲:
foreach
适用于各种可遍历对象,即数组、普通对象(遍历可访问属性的地方)和Traversable
对象(或者更确切地说是定义内部get_iterator
处理程序的对象)。
(source)
简单地说,在普通的PHP编程中,只要一个变量是
一个数组 一个对象而不是
空 资源 标量你可以在上面使用foreach
。
【讨论】:
【参考方案5】:功能
<?php
/**
* Is Array?
* @param mixed $x
* @return bool
*/
function isArray($x) : bool
return !isAssociative($x);
/**
* Is Associative Array?
* @param mixed $x
* @return bool
*/
function isAssociative($x) : bool
if (!is_array($array))
return false;
$i = count($array);
while ($i > 0)
if (!isset($array[--$i]))
return true;
return false;
示例
<?php
$arr = [ 'foo', 'bar' ];
$obj = [ 'foo' => 'bar' ];
var_dump(isAssociative($arr));
# bool(false)
var_dump(isAssociative($obj));
# bool(true)
var_dump(isArray($obj));
# bool(false)
var_dump(isArray($arr));
# bool(true)
【讨论】:
【参考方案6】:从 PHP 7.1 开始,就有一个伪类型 iterable
用于此目的。类型提示iterable
接受任何数组以及Traversable
接口的任何实现。 PHP 7.1 还引入了函数is_iterable()
。对于旧版本,请参阅此处的其他答案,以在不使用较新的内置功能的情况下完成等效的类型强制。
公平竞争:正如 BlackHole 指出的那样,这个问题似乎与 Iterable objects and array type hinting? 重复,his or her answer 比我的更详细。
【讨论】:
【参考方案7】:PHP 7.1.0 has introduced iterable
pseudo-type and the is_iterable()
function,专门为此目的设计的:
这个 […] 提出了一个新的
iterable
伪类型。这种类型类似于callable
,接受多种类型而不是一种类型。
iterable
接受任何array
或实现Traversable
的对象。这两种类型都可以使用foreach
进行迭代,并且可以在生成器中与yield
一起使用。
function foo(iterable $iterable)
foreach ($iterable as $value)
// ...
这个 […] 还添加了一个函数
is_iterable()
,它返回一个布尔值:true
如果一个值是可迭代的并且将被iterable
伪类型接受,false
用于其他值。
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)
您也可以使用函数is_array($var)
来检查传递的变量是否为数组:
<?php
var_dump( is_array(array()) ); // true
var_dump( is_array(array(1, 2, 3)) ); // true
var_dump( is_array($_SERVER) ); // true
?>
阅读更多How to check if a variable is an array in PHP?
【讨论】:
以上是关于如何检查变量是不是为数组?...或类似数组的东西的主要内容,如果未能解决你的问题,请参考以下文章