Ungültiges Argument für foreach() angegeben

Lesezeit: 6 Minuten

Ungultiges Argument fur foreach angegeben
Roberto Alois

Es passiert mir oft, Daten zu verarbeiten, die entweder ein Array oder eine Nullvariable sein können, und einige zu füttern foreach mit diesen Daten.

$values = get_values();

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

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

Warnung: Ungültiges Argument für foreach() in angegeben […]

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

  • Gießen $values zu ordnen
  • Initialisierung $values zu ordnen
  • Einpacken der foreach mit einem if
  • Andere (bitte vorschlagen)

  • Es ist sehr wahrscheinlich, dass die $values ist kein Array.

    – Bhargav Nanekalva

    8. Dezember 2017 um 10:37 Uhr

Ungultiges Argument fur foreach angegeben
Andy Shellam

Persönlich finde ich das am saubersten – ich bin mir nicht sicher, ob es am effizientesten ist, wohlgemerkt!

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

Der Grund für meine Präferenz ist, dass es kein leeres Array zuweist, wenn Sie ohnehin nichts zu beginnen haben.

  • Oder verwenden Sie count(), um herauszufinden, ob das Array nicht leer ist

    – Kem

    13. April 2010 um 13:59 Uhr

  • @ Kemo: count() ist nicht zuverlässig. Wenn Sie bestehen count() null, gibt es 0 zurück. Wenn Sie ihm ein Nicht-Null-Argument übergeben, das kein Array ist, gibt es 1 zurück. Daher ist es unmöglich, es zu verwenden count() um festzustellen, ob die Variable ein Array ist, wenn die Variable ein leeres Array oder ein Array mit 1 Element sein könnte.

    – Andy Shellam

    13. April 2010 um 14:03 Uhr

  • Beachten Sie, dass einige Objekte iterierbar sind und diese Antwort diese nicht berücksichtigt.

    – Brad Koch

    11. Juli 2013 um 20:13 Uhr

  • Sollte sein if (is_array($values) || $values instanceof Traversable).

    – Bob Stein

    7. März 2014 um 2:41 Uhr

  • Heutzutage, is_iterable() ist, wo es ist

    – Die Onin

    2. Dezember 2019 um 14:49 Uhr


Wie wäre es mit diesem? viel sauberer und alles in einer Zeile.

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

  • Dies ist das einzige, was für mich funktioniert hat. Aus irgendeinem Grund glaubte PHP nicht, dass das von mir erstellte mehrdimensionale Array tatsächlich ein Array von Arrays war.

    – Justin

    29. Juli 2015 um 20:21 Uhr

  • Auch hier ist dies eine sehr nette Lösung für ein Array, das entweder Arrays oder Nullwerte enthält. Fügen Sie einfach einen Test in der foreach-Schleife hinzu, um fortzufahren, wenn die Daten null sind.

    – Eidechse

    26. Januar 2016 um 0:37 Uhr

  • Mein Problem gelöst. Danke!

    – Hitsch

    3. April 2016 um 7:39 Uhr

  • Brillanter Code, übersprungen das if, sonst für Array- und Nicht-Array-Wert mit $_POST mit Kontrollkästchen!

    – Yann Chabot

    9. Mai 2016 um 19:27 Uhr

  • HINWEIS: Diese Methode sieht zwar schön aus und löst die ungültige foreach-Warnung auf, gibt jedoch eine Warnung über eine undefinierte Variable zurück, wenn die Variable in keiner Weise festgelegt ist. Verwenden isset() oder is_array() oder beides, ganz abhängig von Ihrem Szenario usw.

    – James

    22. Juli 2016 um 13:26 Uhr

1647057848 432 Ungultiges Argument fur foreach angegeben
Kris

Ich verwende normalerweise 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 spezielle Version nicht getestet wurde, sie wird direkt aus dem Speicher in SO eingegeben.

Bearbeiten: hinzugefügt Überfahrbar prüfen

  • Beste Antwort. Außer ich denke, Sie sollten wirklich überprüfen, ob $var instanceof Traversable. Sehen Hier. Denn zum Beispiel kann man a foreachen SimpleXMLElementaber es ist keine Instanz von Iterator oder IteratorAggregate.

    – Bob Stein

    7. März 2014 um 2:38 Uhr

  • Möglicherweise können Sie die anderen beiden Klassen entfernen, @Kris. Beide verlängern Überfahrbar jetzt und scheinen so in 5.0.0 geboren worden zu sein. Obwohl ich einen kleinen Zweifel habe, ob instanceof immer auf erstreckt sich.

    – Bob Stein

    8. März 2014 um 10:44 Uhr


  • @BobStein-VisiBone: ja (außer sie sind Schnittstellen, keine Klassen) Allerdings; Ich habe Traversable vor diesen eingefügt, weder Iterator noch IteratorAggregate müssten jemals überprüft werden (auf diese Weise werden sie die Ausführung nicht verlangsamen). Ich habe sie gelassen, um die Antwort so nah wie möglich an der ursprünglichen Antwort zu halten, die ich gegeben habe, und um sie offensichtlich/lesbar zu halten.

    – Kris

    14. März 2014 um 6:51 Uhr

  • Ich denke, es wäre fair, hinzuzufügen is_object($var) betreffend. php.net/manual/en/language.oop5.iterations.php

    – Markus Fuchs

    23. Juli 2014 um 22:53 Uhr

  • @MarkFox: Fühlen Sie sich frei, aber ich habe es absichtlich weggelassen; Ich habe noch nie eine Verwendung dafür gesehen, die nicht besser durch die Implementierung gedient wäre Iterator oder IteratorAggregateaber das ist natürlich nur meine Meinung und daher subjektiv (öffentliche Felder verwende ich nie).

    – Kris

    28. Juli 2014 um 7:34 Uhr

Ungultiges Argument fur foreach angegeben
AARTT

Bitte verlassen Sie sich nicht auf das Gießen als Lösungobwohl andere dies als gültige Option zum Verhindern eines Fehlers vorschlagen, kann es zu einem anderen führen.

Sei vorsichtig: Wenn Sie erwarten, dass eine bestimmte Form von Array zurückgegeben wird, kann dies fehlschlagen. Dafür sind weitere Kontrollen erforderlich.

ZB Casting eines booleschen Werts in ein Array (array)boolWille NICHT Ergebnis ist ein leeres Array, aber ein Array mit einem Element, das den booleschen Wert als int enthält: [0=>0] oder [0=>1].

Ich habe einen Schnelltest geschrieben, um dieses Problem darzustellen. (Hier ist ein Sicherungstest falls die erste Test-URL fehlschlägt.)

Enthalten sind Tests für: null, false, trueein classein array und undefined.


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

  1. Schnelle Typprüfung: $array = is_array($var) or is_object($var) ? $var : [] ;
  2. Geben Sie Hinting-Arrays ein in Methoden vor der Verwendung eines foreach und Angabe von Rückgabetypen
  3. Umhüllen von foreach in if
  4. Verwenden try{}catch(){} Blöcke
  5. Entwerfen des richtigen Codes / Testen vor Produktionsfreigaben
  6. Um ein Array auf die richtige Form zu testen, könnten Sie verwenden array_key_exists auf einem bestimmten Schlüssel, oder testen Sie die Tiefe eines Arrays (wenn es eins ist!).
  7. Extrahieren Sie Ihre Hilfsmethoden immer in den globalen Namensraum, um doppelten Code zu reduzieren

1647057849 761 Ungultiges Argument fur foreach angegeben
GigolNet Guigolachvili

Versuche dies:

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

😉

  • Dies funktioniert nicht gut mit assoziativen Arrays. Die is_array-Methode ist insgesamt besser … und einfacher …

    – AO_

    14. Juli 2014 um 13:49 Uhr

$values = get_values();

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

Problem ist immer null und Casting ist in der Tat die Reinigungslösung.

  • Dies funktioniert nicht gut mit assoziativen Arrays. Die is_array-Methode ist insgesamt besser … und einfacher …

    – AO_

    14. Juli 2014 um 13:49 Uhr

1647057850 166 Ungultiges Argument fur foreach angegeben
Ihr gesunder Menschenverstand

Zunächst muss jede Variable initialisiert werden. Immer.
Casting ist keine Option.
wenn get_values ​​(); Variablen unterschiedlichen Typs zurückgeben können, muss dieser Wert natürlich überprüft werden.

  • Casting ist eine Option – wenn Sie ein Array mit initialisieren $array = (array)null; Sie erhalten ein leeres Array. Natürlich ist es eine Verschwendung von Speicherzuweisung 😉

    – Andy Shellam

    13. April 2010 um 14:13 Uhr


  • +1: Aus sentimentaler Sicht lesen, es ist mir egal, ob die Sprache ohne Variablen auskommt MUSS deklariert werden und unzuverlässige Ergebnisse MUSS überprüft werden. Es ist erforderlich, um den/die Entwickler bei Verstand zu halten und die Fehlerprotokolle kurz zu halten.

    – Kris

    27. März 2013 um 9:23 Uhr

  • Das ist weit und weg die beste Antwort auf diese Frage. Wenn Sie versuchen, etwas zu iterieren, erwarten Sie eindeutig, dass es iterierbar ist. Es zu casten oder zu überprüfen, ob es iterierbar ist, ist Zeitverschwendung, da es lediglich die Tatsache verschleiert, dass die Variable nicht das enthält, was Sie denken, was sie bedeutet, also die tatsächlich Problem ist woanders in Ihrem Code.

    – Nick

    22. Februar 2021 um 4:47 Uhr

992630cookie-checkUngültiges Argument für foreach() angegeben

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy