如何在PHP中检查数组


How to check for arrayness in PHP?

我能想到的最好的是

function is_array_alike($array) {
  return is_array($array) || (is_object($array) && $array instanceof ArrayAccess && $array instanceof Traversable && $array instanceof Serializable && $array instanceof Countable);
}

啊。还有更漂亮的吗?

编辑:is_object的测试似乎没有必要。我在PHP手册的instanceof中添加了一节关于这一点的内容。

好吧,因为你在帖子中确实使用了"漂亮"一词,所以为了可读性,只需要简单地修改一下外观:

function is_array_or_alike($var) {
  return is_array($var) ||
           ($var instanceof ArrayAccess  &&
            $var instanceof Traversable  &&
            $var instanceof Serializable &&
            $var instanceof Countable);
}

更改说明:

  1. 函数名称更改:"is_array_alike"->"is_array_or_alike"只是为了清楚地表明数组和相似性都在测试中。

  2. 参数/参数名称更改:$array->$var,因为"$array"已经在某种程度上预设了参数的类型为数组。

  3. 堆叠&'可读性和符合Drupal编码标准的条件:最多80个字符行。由于您是Drupal核心维护人员之一,我想我假设这个函数可能会进入Drupal,所以您可能在提交之前就已经完成了。

  4. 您认为is_object()是不必要的,这是正确的。在Java中,这是必要的,因为如果第一个操作数不是对象,instanceof会引发编译时错误,但我刚才在PHP中检查了一下,没有错误,只是bool(false)的结果。

我赞同paulmatthews86关于你提供一个用例的建议。如果我们不知道标准,就很难提供建议。例如,借用鸭子类型范式的观点,instanceof测试是有用的,但不一定是强制性的,甚至不一定是完整的。如果您更感兴趣的是$var可以做什么以及它在某些上下文中的行为,那么您可以使用反射来检查是否存在稍后需要在其上调用的方法,或者您可以测试它在传递给数组函数时的行为是否如预期。例如,它与array_udiff_assocarray_chunk等一起"工作"吗?如果这些行为对您的用例更重要,那么这些测试可能会取代instanceof类型的测试,当然会有很多重叠。

希望这能有所帮助。有兴趣看看如果你决定发布它,你最终会做出什么决定。

php中有迭代器接口http://php.net/manual/en/class.iterator.php

使用

function isIter($abc) {
    return (is_array($abc) || $abc instanceof Traversable);
}

即使ArrayObject实现了Serializable,但对象必须实现为类似数组的假设是错误的。

情况恰恰相反。您可以使用Serializable来有效地防止对象的序列化。所以我会考虑将其从接口检查中删除。

此外,如果您在没有对象的情况下使用instanceof,您将看到一个(致命)错误。我建议您将对"类数组"对象的检查委托给叶函数,并使您对输入类型不太严格的函数使用它:

function is_array_or_object_arraylike($var) {
    return is_array($var) 
        || (is_object($var) && is_object_arraylike($var))
        ;
}
function is_object_arraylike($obj) {
    return $obj instanceof ArrayAccess
        && $obj instanceof Traversable
        && $obj instanceof Countable
        ;
}

还要记住,即使对象是类似数组的,它也不能与大多数数组函数一起使用。它也不能很好地与foreach配合使用,因此您应该更好地概述您在这里寻找的阵列功能。

这里有一个新的PHP 7.3规范,它实现了is_countable函数https://wiki.php.net/rfc/is-countable

基于规范&对于以前的PHP版本,您可以使用此

if (is_array($foo) || $foo instanceof Countable) {
    return count($foo);
}

或者你也可以实现一种类似的polyfill

if (!function_exists('is_countable')) {
    function is_countable($c) {
        return is_array($c) || $c instanceof Countable;
    }
}