409 Stimmen

Ungültiges Argument für foreach() geliefert

Es passiert mir oft, dass ich Daten verarbeiten muss, die entweder ein Array oder eine Null-Variable sein können, und dass ich einige foreach mit diesen Daten.

$values = get_values();

foreach ($values as $value){
  ...
}

Wenn Sie eine foreach mit Daten füttern, die kein Array sind, erhalten Sie eine Warnung:

Warnung: Ungültiges Argument geliefert für foreach() in [...]

Angenommen, es ist nicht möglich, die get_values() Funktion immer ein Array zurückgeben (Abwärtskompatibilität, nicht verfügbarer Quellcode, welcher Grund auch immer), frage ich mich, was der sauberste und effizienteste Weg ist, um diese Warnungen zu vermeiden:

  • Gießen $values zum Array
  • Initialisierung $values zum Array
  • Einpacken der foreach mit einer if
  • Sonstiges (bitte vorschlagen)

639voto

Andy Shellam Punkte 14907

Ich persönlich finde, dass dies die sauberste Methode ist - ob sie auch die effizienteste ist, weiß ich nicht!

if (is_array($values) || is_object($values))
{
    foreach ($values as $value)
    {
        ...
    }
}

Der Grund für meine Präferenz ist es nicht zuweisen ein leeres Array, wenn Sie nichts, um mit sowieso zu beginnen haben.

174voto

Ajith R Nair Punkte 2042

Wie wäre es damit? Viel sauberer und alles in einer Zeile.

foreach ((array) $items as $item) {
 // ...
 }

50voto

Kris Punkte 38235

Ich verwende in der Regel ein ähnliches Konstrukt wie dieses:

/**
 * Determine if a variable is iterable. i.e. can be used to loop over.
 *
 * @return bool
 */
function is_iterable($var)
{
    return $var !== null 
        && (is_array($var) 
            || $var instanceof Traversable 
            || $var instanceof Iterator 
            || $var instanceof IteratorAggregate
            );
}

$values = get_values();

if (is_iterable($values))
{
    foreach ($values as $value)
    {
        // do stuff...
    }
}

Beachten Sie, dass diese Version nicht getestet ist, sondern direkt aus dem Gedächtnis in SO eingegeben wurde.

Editer : hinzugefügt. Überfahrbar siehe

20voto

AARTT Punkte 463

Bitte verlassen Sie sich nicht auf das Gießen als Lösung , auch wenn andere dies als gültige Option zur Vermeidung eines Fehlers vorschlagen, könnte es einen weiteren Fehler verursachen.

Seien Sie sich dessen bewusst: Wenn Sie erwarten, dass eine bestimmte Form von Array zurückgegeben wird, könnte dies fehlschlagen. Hierfür sind weitere Prüfungen erforderlich.

Z.B. Umwandlung eines booleschen Wertes in ein Array (array)bool wird NICHT ergeben ein leeres Array, aber ein Array mit einem Element, das den booleschen Wert als int enthält: [0=>0] o [0=>1] .

Ich habe einen kurzen Test geschrieben, um dieses Problem darzustellen . (Hier ist eine Backup-Test für den Fall, dass die erste Testurl fehlschlägt).

Enthalten sind Tests für: null , false , true , a class an array y undefined .


Testen Sie Ihre Eingaben immer, bevor Sie sie in foreach verwenden. Vorschläge:

  1. Schnelle Typenprüfung : $array = is_array($var) or is_object($var) ? $var : [] ;
  2. Typ-Hinweis-Arrays in Methoden vor der Verwendung einer foreach- und Angabe der Rückgabearten
  3. Verschachtelung von foreach innerhalb von if
  4. Verwendung von try{}catch(){} Blöcke
  5. Entwurf eines geeigneten Codes / Tests vor der Produktionsfreigabe
  6. Um ein Array auf seine korrekte Form zu prüfen, können Sie Folgendes verwenden array_key_exists auf eine bestimmte Taste, oder die Tiefe eines Arrays testen (wenn es eins ist!) .
  7. Extrahieren Sie Ihre Hilfsmethoden immer in den globalen Namespace, um doppelten Code zu vermeiden.

14voto

GigolNft Punkte 731

Versuchen Sie dies:

//Force array
$dataArr = is_array($dataArr) ? $dataArr : array($dataArr);
foreach ($dataArr as $val) {
  echo $val;
}

;)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X