Как проверить, является ли переменная массивом?... или что-то вроде массива
Я хочу использовать цикл foreach
с переменной, но эта переменная может быть много разных типов, например NULL
.
Итак, перед foreach
я тестирую его:
if(is_array($var)){
foreach($var as ...
Но я понял, что это также может быть класс, реализующий интерфейс Iterator
. Может быть, я слепой, но как проверить, реализует ли класс интерфейс? Есть что-то вроде функции is_a
или оператора inherits
? Я нашел class_implements
, я могу использовать его, но, может быть, есть что-то более простое?
И во-вторых, что более важно, я полагаю, что эта функция существует, было бы достаточно, чтобы проверить, существует ли переменная is_array
или "реализует интерфейс Iterator
" или мне нужно проверить что-то еще?
Ответы
Ответ 1
Если вы используете foreach
внутри функции, и вы ожидаете массив или объект Traversable, вы можете ввести подсказку о том, что функция с:
function myFunction(array $a)
function myFunction(Traversable)
Если вы не используете foreach
внутри функции или вы ожидаете как вы можете просто использовать эту конструкцию, чтобы проверить, можете ли вы выполнять итерацию над переменной:
if (is_array($a) or ($a instanceof Traversable))
Ответ 2
foreach
может обрабатывать массивы и объекты. Вы можете проверить это с помощью:
$can_foreach = is_array($var) || is_object($var);
if ($can_foreach) {
foreach ($var as ...
}
Вам не нужно специально проверять Traversable
как другие намекают на это в своих ответах, потому что все объекты - как и все массивы - являются проходимыми в PHP.
Более технически:
foreach
работает со всеми видами traversables, то есть с массивами, с простыми объектами (где get_iterator
доступные свойства) и объектами Traversable
(или, скорее, объектами, которые определяют внутренний обработчик get_iterator
).
(источник)
Проще говоря, в обычном программировании PHP, когда переменная
и не
Вы можете использовать foreach
на нем.
Ответ 3
Вы можете проверить экземпляр Traversable
с помощью простой функции. Это будет работать для всего этого Iterator
, потому что Iterator extends Traversable
function canLoop($mixed) {
return is_array($mixed) || $mixed instanceof Traversable ? true : false;
}
Ответ 4
<?php
$var = new ArrayIterator();
var_dump(is_array($var), ($var instanceof ArrayIterator));
возвращает bool(false)
или bool(true)
Ответ 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 и подсказок типа массива? и его или ее ответ становится более подробным, чем мой.