16

我能想到的最好的方法是

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似乎没有必要。我在 instanceof PHP 手册中添加了一个关于此的部分。

4

4 回答 4

11

好吧,既然你在帖子中确实使用了“漂亮”这个词,只是为了提高可读性而对外观进行快速建议:

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. 堆叠 &&'ed 条件以提高可读性和符合 Drupal 编码标准:最大 80 字符行。由于您是 Drupal 核心维护者之一,我想我假设此功能可能会进入 Drupal,因此您可能会在提交之前完成此操作。

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

我同意 paulmatthews86 的建议,即您提供一个用例。如果我们不知道标准,就很难提供建议。例如,从鸭式范式的角度借用一点,instanceof测试会很有用,但不一定是强制性的,甚至不一定是完整的。如果您对 can 做什么以及它在某些上下文中的行为方式更感兴趣,$var那么您可以使用反射来检查是否存在需要稍后对其调用的方法,或者您可以测试它在通过时是否按预期运行到数组函数。例如,它是否与array_udiff_assoc,array_chunk等一起“工作”。如果这些行为对您的用例更重要,那么这些测试可能会取代instanceof类型测试,尽管当然会有很多重叠。

希望这可以帮助。如果您决定发布它,有兴趣看看您最终决定的内容。

于 2012-09-11T16:58:25.893 回答
1

即使ArrayObjectimplements 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,因此您应该更好地概述您在此处寻找的数组功能。

于 2012-10-04T17:25:29.237 回答
1

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

利用

function isIter($abc) {
    return (is_array($abc) || $abc instanceof Traversable);
}
于 2012-09-10T07:23:16.633 回答
0

有一个 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;
    }

}
于 2018-04-18T13:48:21.703 回答