Ich möchte eine foreach
-Schleife mit einer Variablen verwenden, aber diese Variable kann viele verschiedene Typen haben, beispielsweise NULL
.
Also bevor ich foreach
teste:
if(is_array($var)){
foreach($var as ...
Mir wurde jedoch klar, dass es auch eine Klasse sein kann, die Iterator
interface implementiert. Vielleicht bin ich blind, aber wie prüfe ich, ob die Klasse Interface implementiert? Gibt es etwas wie is_a
-Funktion oder inherits
-Operator? Ich habe class_implements
gefunden, ich kann es verwenden, aber vielleicht gibt es etwas Einfacheres?
Und zweitens, was noch wichtiger ist, ich glaube, diese Funktion existiert, würde ausreichen, um zu prüfen, ob die Variable is_array
oder "implementiert Iterator
interface" oder soll ich noch etwas testen?
Wenn Sie foreach
in einer Funktion verwenden und ein Array oder ein Traversable - Objekt erwarten, können Sie diese Funktion mit folgendem Befehl eingeben:
function myFunction(array $a)
function myFunction(Traversable)
Wenn Sie nicht foreach
in einer Funktion verwenden oder Sie erwarten, dass Sie verwenden, können Sie dieses Konstrukt einfach verwenden, um zu prüfen, ob Sie die Variable durchlaufen können:
if (is_array($a) or ($a instanceof Traversable))
foreach
kann Arrays und Objekte verarbeiten. Sie können dies überprüfen mit:
$can_foreach = is_array($var) || is_object($var);
if ($can_foreach) {
foreach ($var as ...
}
Sie müssen nicht speziell nach Traversable
suchen, da andere dies in ihren Antworten angedeutet haben, da alle Objekte - wie alle Arrays - in PHP durchlaufbar sind.
Technisch mehr:
foreach
arbeitet mit allen Arten von Traversables, d. h. mit Arrays, mit einfachen Objekten (wobei die zugänglichen Eigenschaften durchlaufen werden) undTraversable
-Objekten (bzw. Objekten, die den internenget_iterator
-Handler definieren).
( Quelle )
Einfach gesagt in der allgemeinen PHP Programmierung, wann immer eine Variable ist
und ist nicht
sie können foreach
darauf verwenden.
Sie können die Instanz von Traversable
mit einer einfachen Funktion überprüfen. Dies würde für all das von Iterator
funktionieren, weil Iterator extends Traversable
function canLoop($mixed) {
return is_array($mixed) || $mixed instanceof Traversable ? true : false;
}
<?php
$var = new ArrayIterator();
var_dump(is_array($var), ($var instanceof ArrayIterator));
gibt bool(false)
oder bool(true)
zurück
<?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)
Seit PHP 7.1 gibt es genau für diesen Zweck einen Pseudo-Typ iterable
. Der Typhinweis iterable
akzeptiert jedes Array sowie jede Implementierung der Traversable
-Schnittstelle. PHP 7.1 führte auch die Funktion is_iterable()
ein. Bei älteren Versionen finden Sie weitere Antworten hier, um die Ersetzung des gleichwertigen Typs ohne die neueren integrierten Funktionen zu erreichen.
Fairplay: Wie BlackHole darauf hinweist, scheint diese Frage ein Duplikat von Iterable Objects und Array-Typ-Hinweisen zu sein. und seine oder ihre Antwort geht weiter ins Detail als meine.