как проверить, является ли переменная массивом? ... или чем-то похожим на массив

<p>я хочу использовать цикл <code>foreach</code> с переменной, но эта переменная может быть разных типов, например <code>null</code>.</p><p>поэтому перед <code>foreach</code> я проверяю это:</p><pre><code>if(is\_array($var)){ foreach($var as ... </code></pre><p>но я понял, что это также может быть класс, реализующий интерфейс <code>iterator</code>. может быть, я слепой, но как проверить, реализует ли класс интерфейс? есть ли что-то вроде функции <code>is\_a</code> или оператора <code>inherits</code>? я нашел <code>class\_implements</code>, я могу использовать его, но, может быть, есть что-то попроще?</p><p>и, во-вторых, что более важно, я полагаю, что эта функция существует, будет достаточно, чтобы проверить, является ли переменная <code>is\_array</code> или «реализует интерфейс <code>iterator</code>», или мне следует проверить что-то большее?</p>

<p>если вы используете <code>foreach</code> внутри функции и ожидаете массив или объект <a href="http://php.net/manual/en/class.traversable.php">traversable</a> , вы можете напечатать подсказку этой функции с помощью: </p><pre><code>function myfunction(array $a) function myfunction(traversable) если вы не используете foreach внутри функции или ожидаете обоих <a href="http://www.php.net/manual/en/class.traversable.php#99195">вы можете просто использовать эту конструкцию , чтобы проверить, можете ли вы перебрать переменную:if (is_array($a) or ($a instanceof traversable)) 

 <a href="https://php.net/foreach">foreach может обрабатывать массивы и объекты. вы можете проверить это с помощью:$can\_foreach = is\_array($var) || is_object($var); if ($can_foreach) { foreach ($var as ... } </code></pre><p>вам не нужно специально проверять наличие <a href="https://php.net/traversable"><em><code>traversable</code></em></a> , как другие намекали на это в своих ответах, потому что все объекты - как и все массивы - доступны в php.</p><p>более технически:</p><blockquote> <p><code>foreach</code> работает со всеми видами обходных путей, то есть с массивами, с простыми объектами (где просматриваются доступные свойства) и объектами <code>traversable</code> (или, скорее, объектами, которые определяют внутренний обработчик <code>get\_iterator</code>). </p> </blockquote><p>( <a href="https://stackoverflow.com/a/14854568/367456">источник</a> )</p><p>проще говоря, в обычном php программировании, когда переменная </p><ul> <li>массив</li> <li>объект</li> </ul><p>и <em>не</em></p><ul> <li>ноль</li> <li>ресурс</li> <li>скаляр</li> </ul><p>вы можете использовать <em><code>foreach</code></em> на нем.</p>

<p>вы можете проверить экземпляр <code>traversable</code> с помощью простой функции. это будет работать для всего этого <code>iterator</code>, потому что <code>iterator extends traversable</code></p><pre><code>function canloop($mixed) { return is_array($mixed) || $mixed instanceof traversable ? true : false; } 

<?php $var = new arrayiterator(); var\_dump(is\_array($var), ($var instanceof arrayiterator)); </code></pre><p>возвращает <code>bool(false)</code> или <code>bool(true)</code></p>

<h1>функции</h1><pre><code><?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) </code></pre>

<p>поскольку php 7.1 существует псевдотип <a href="http://php.net/manual/en/language.types.iterable.php"><code>iterable</code></a> именно для этой цели. подсказка типа <code>iterable</code> принимает любой массив, а также любую реализацию интерфейса <code>traversable</code>. php 7.1 также представила функцию <a href="http://php.net/manual/en/function.is-iterable.php"><code>is\_iterable()</code></a> . для более старых версий см. другие ответы здесь для выполнения эквивалентного принудительного исполнения без новых встроенных функций.</p><p>честная игра: как указывал blackhole, этот вопрос кажется дубликатом <a href="https://stackoverflow.com/questions/3584700/iterable-objects-and-array-type-hinting"><em>повторяющихся объектов и подсказок типа массива?</em></a> и <a href="https://stackoverflow.com/a/39320526/3303195">его или ее ответ</a> более подробно, чем мой.</p>