如何检查变量是否是数组?...或类似数组的东西

时间:2013-03-24 21:00:59

标签: php arrays foreach

我想在变量中使用foreach循环,但这个变量可以是多种不同的类型,例如NULL

所以在foreach之前我测试一下:

if(is_array($var)){
  foreach($var as ...

但我意识到它也可以是一个实现Iterator接口的类。也许我是盲人,但如何检查类是否实现接口?有is_a函数或inherits运算符吗?我发现class_implements,我可以使用它,但也许有更简单的东西?

第二,更重要的是,我认为这个函数存在,足以检查变量is_array或“实现Iterator接口”还是应该测试更多的东西?

7 个答案:

答案 0 :(得分:68)

如果你在函数中使用foreach并且你期望一个数组或Traversable对象,你可以输入提示函数:

function myFunction(array $a)
function myFunction(Traversable)

如果你没有在函数中使用foreach,或者你期望you can simply use this construct检查你是否可以迭代变量:

if (is_array($a) or ($a instanceof Traversable))

答案 1 :(得分:12)

foreach可以处理数组和对象。您可以通过以下方式查看:

$can_foreach = is_array($var) || is_object($var);
if ($can_foreach) {
    foreach ($var as ...
}

您不需要专门检查Traversable,因为其他人已经在答案中暗示了它,因为所有对象(如所有数组)都可以在PHP中遍历。

更专业:

  

foreach适用于所有类型的遍历,即使用数组,使用普通对象(遍历可访问属性)和Traversable对象(或者更确切地说定义内部get_iterator的对象处理程序)。

source

简单地说,在常见的PHP编程中,只要变量是

  • 一个数组
  • 一个对象

不是

  • NULL
  • 资源
  • 标量

您可以在其上使用 foreach

答案 2 :(得分:5)

您可以使用简单的功能检查Traversable的实例。这适用于Iterator的所有这一切,因为Iterator extends Traversable

function canLoop($mixed) {
    return is_array($mixed) || $mixed instanceof Traversable ? true : false;
}

答案 3 :(得分:2)

<?php
$var = new ArrayIterator();

var_dump(is_array($var), ($var instanceof ArrayIterator));

返回bool(false)bool(true)

答案 4 :(得分:1)

PHP 7.1.0 has introduced iterable pseudo-type and the is_iterable() function,专为此目的而设计:

<块引用>

这个 […] 提出了一个新的 b = np.insert(a, slice(0,2), a, 2) b = np.insert(b, slice(0,2), b, 1) b = np.insert(b, slice(0,2), b, 0) 伪类型。这种类型类似于 array([[[ 1, 1, 2, 2], [ 1, 1, 2, 2], [-2, -2, -1, -1], [-2, -2, -1, -1]], [[ 1, 1, 2, 2], [ 1, 1, 2, 2], [-2, -2, -1, -1], [-2, -2, -1, -1]], [[ 3, 3, -4, -4], [ 3, 3, -4, -4], [ 4, 4, -3, -3], [ 4, 4, -3, -3]], [[ 3, 3, -4, -4], [ 3, 3, -4, -4], [ 4, 4, -3, -3], [ 4, 4, -3, -3]]]) ,接受多种类型而不是单一类型。

a 接受任何 for axis in range(3): a = np.insert(a, slice(0,2), a, axis) 或实现 iterable 的对象。这两种类型都可以使用 callable 进行迭代,并且可以在生成器中与 iterable 一起使用。

array
<块引用>

这个 […] 还添加了一个函数 Traversable,它返回一个布尔值:foreach 如果一个值是可迭代的并且将被 yield 伪类型接受,{{1} } 用于其他值。

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

您也可以使用函数 is_iterable() 来检查传递的变量是否为数组:

true

How to check if a variable is an array in PHP?中阅读更多

答案 5 :(得分:0)

功能

<?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 :(得分:0)

自PHP 7.1起,就有一个伪类型iterable用于此目的。类型提示iterable接受任何数组以及Traversable接口的任何实现。 PHP 7.1还引入了功能is_iterable()。对于较旧的版本,请参见此处的其他答案,以在没有较新的内置功能的情况下完成等效类型的强制实施。

公平竞争:正如BlackHole所指出的那样,这个问题似乎是Iterable objects and array type hinting?的重复,而his or her answer的细节比我的还要详细。