Как проверить на массивность в PHP? - программирование

Как проверить на массивность в 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 экземпляра PHP.

4b9b3361

Ответ 1

Хорошо, так как вы использовали слово "pretty" в своем посте, просто быстрое предложение о косметических изменениях для удобочитаемости:

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

Объяснение изменений:

  • Изменение имени функции: "is_array_alike" → "is_array_or_alike", чтобы было ясно, что тестируются как массивы, так и аналогичные.

  • Изменение имени параметра/аргумента: $array$var, потому что "$array" уже является предпосылкой того, что аргумент имеет массив типов.

  • Установки и 'ed условия для удобочитаемости и соответствия стандарту кодирования Drupal: 80- char line max. Поскольку вы являетесь одним из разработчиков ядра Drupal, я предполагаю, что я предполагаю, что эта функция, возможно, войдет в Drupal, так что, возможно, вы сделали бы это до того, как все это закончите.

  • Вы правы, что is_object() не требуется. В Java это было бы необходимо, потому что instanceof выдавал ошибку времени компиляции, если первый операнд не был объектом, но я только что проверил в PHP и нет ошибки, просто результат bool (false).

I второе предложение paulmatthews86 о том, что вы предоставляете прецедент. Трудно дать рекомендации, если мы не знаем критериев. Например, чтобы одолжить немного с точки зрения парадигмы утки, тесты instanceof были бы полезны, но не обязательно обязательно или даже полностью. Если вас больше интересует то, что может сделать $var и то, как он ведет себя в определенных контекстах, тогда вы можете использовать отражение, чтобы проверить наличие методов, которые нужно вызвать на нем позже, или вы можете проверить, что он ведет себя как ожидается при передаче функций массива. например Работает ли он с array_udiff_assoc, array_chunk и т.д. Если эти поведения более важны для ваших случаев использования, тогда эти тесты могут заменить типовое тестирование instanceof, хотя, конечно, будет много перекрытий.

Надеюсь, это поможет. Заинтересованы в том, чтобы узнать, что вы, наконец, решите, если вы решите опубликовать его.

Ответ 2

есть интерфейс итератора в php http://php.net/manual/en/class.iterator.php

использовать

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

Ответ 3

Даже если 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, поэтому вам следует лучше описать, какие функции массива вы ищете здесь.