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
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
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.
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.
@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
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].
Entwerfen des richtigen Codes / Testen vor Produktionsfreigaben
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!).
Extrahieren Sie Ihre Hilfsmethoden immer in den globalen Namensraum, um doppelten Code zu reduzieren
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
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
9926300cookie-checkUngültiges Argument für foreach() angegebenyes
Es ist sehr wahrscheinlich, dass die
$values
ist kein Array.– Bhargav Nanekalva
8. Dezember 2017 um 10:37 Uhr