Nieprawidłowy argument podany dla foreach()
Często zdarza mi się obsługiwać dane, które mogą być tablicą lub zmienną null i karmić nimi niektóre foreach
.
$values = get_values();
foreach ($values as $value){
...
}
Kiedy karmisz foreach danymi, które nie są tablicami, otrzymujesz Ostrzeżenie:
Warning: Invalid argument supplied for foreach () in [...]
Zakładając, że nie jest możliwe refaktorowanie funkcji get_values()
, aby zawsze zwracała tablicę (wsteczna kompatybilność, niedostępny kod źródłowy, niezależnie od innych powodów), zastanawiam się który jest najczystszym i najskuteczniejszym sposobem uniknięcia tych ostrzeżeń:
- Casting
$values
do tablicy - Inicjalizacja
$values
do tablicy - owijanie
foreach
zif
- Inne (proszę sugerować)
18 answers
[1]} osobiście uważam, że jest to najbardziej czyste - Nie wiem, czy jest to najbardziej wydajne, umysł!
if (is_array($values) || is_object($values))
{
foreach ($values as $value)
{
...
}
}
Powodem moich preferencji jest to, że nie przydziela pustej tablicy, gdy i tak nie masz nic na początek.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-27 20:57:40
A może ten? dużo czystsze i wszystko w jednej linii.
foreach ((array) $items as $item) {
// ...
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-08 17:08:27
Zwykle używam konstrukcji podobnej do tej:
/**
* 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...
}
}
Zauważ, że ta konkretna wersja nie jest testowana, jest wpisywana bezpośrednio do SO z pamięci.
Edit: added Traversable check
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-25 13:47:49
Proszę nie zależeć od odlewania jako rozwiązania , nawet jeśli inni sugerują to jako ważną opcję, aby zapobiec błędowi, może to spowodować inny.
Be aware: Jeśli spodziewasz się, że zostanie zwrócona określona forma tablicy, może to cię zawieść. W tym celu wymagana jest większa liczba kontroli.
Np. dodanie elementu logicznego do tablicy
(array)bool
, spowoduje NIE powstanie pusta tablica, ale tablica z jednym elementem zawierającym wartość logiczną jako int:[0=>0]
lub[0=>1]
.
Napisałem szybki test, aby przedstawić ten problem . (Tutaj jest test kopii zapasowej na wypadek, gdyby pierwszy testowy url nie powiódł się.)
W zestawie znajdują się testy na: null
, false
, true
, a class
, an array
i undefined
.
Zawsze przetestuj swoje wejście przed użyciem go w foreach. Sugestie:
-
szybkie sprawdzanie typu :
$array = is_array($var) or is_object($var) ? $var : [] ;
- wpisz tablice hinting w metodach przed użyciem foreach i określanie typów zwracanych
- owijanie foreach wewnątrz if
- użycie
try{}catch(){}
bloków - projektowanie właściwego kodu / testowanie przed wydaniami produkcyjnymi
- aby przetestować tablicę pod odpowiednim formularzem, możesz użyć
array_key_exists
na określonym kluczu, lub przetestować głębokość tablicy (gdy jest ona jedna !). - zawsze wyodrębniaj metody pomocnicze do globalnej przestrzeni nazw, aby zmniejszyć zduplikowany kod
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:54
Spróbuj tego:
//Force array
$dataArr = is_array($dataArr) ? $dataArr : array($dataArr);
foreach ($dataArr as $val) {
echo $val;
}
;)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-30 12:52:18
$values = get_values();
foreach ((array) $values as $value){
...
}
Problem jest zawsze zerowy, a odlewanie jest w rzeczywistości rozwiązaniem czyszczącym.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-02 16:59:44
Po pierwsze, każda zmienna musi być zainicjalizowana. Zawsze.
Casting nie wchodzi w grę.
jeśli get_values (); może zwrócić zmienną innego typu, to ta wartość musi być oczywiście sprawdzona.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-13 14:11:25
Bardziej zwięzłe rozszerzenie @ Kod Krisa
function secure_iterable($var)
{
return is_iterable($var) ? $var : array();
}
foreach (secure_iterable($values) as $value)
{
//do stuff...
}
Szczególnie do użycia wewnątrz kodu szablonu
<?php foreach (secure_iterable($values) as $value): ?>
...
<?php endforeach; ?>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:24
foreach ($arr ? $arr : [] as $elem) {
// Does something
}
Nie sprawdza, czy jest to tablica, ale pomija pętlę, jeśli zmienna ma wartość null lub pustą tablicę.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-14 02:41:50
Jeśli używasz php7 i chcesz obsłużyć tylko niezdefiniowane błędy to jest to najczystsze IMHO
$array = [1,2,3,4];
foreach ( $array ?? [] as $item ) {
echo $item;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-09 15:27:03
Nie jestem pewien, czy tak jest, ale ten problem wydaje się występować wiele razy podczas migracji witryn wordpress lub migracji dynamicznych witryn w ogóle. W takim przypadku upewnij się, że hosting, na który migrujesz, używa tej samej wersji PHP, której używa Twoja stara witryna.
Jeśli nie migrujesz witryny i jest to tylko problem, który pojawił się spróbuj zaktualizować do PHP 5. To rozwiązuje niektóre z tych problemów. Może wydawać się głupie rozwiązanie, ale zrobił sztuczkę dla mnie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-12 13:16:28
Wyjątkowy przypadek dla tego powiadomienia występuje, jeśli ustawisz tablicę na null wewnątrz pętli foreach
if (is_array($values))
{
foreach ($values as $value)
{
$values = null;//WARNING!!!
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-18 09:24:52
Co powiesz na to rozwiązanie:
$type = gettype($your_iteratable);
$types = array(
'array',
'object'
);
if (in_array($type, $types)) {
// foreach code comes here
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-01 12:04:11
Wydaje się również, że istnieje związek ze środowiskiem:
Miałem ten błąd "invalid argument supplied foreach ()" tylko w środowisku dev, ale nie w prod( pracuję na serwerze, nie na localhost).
Pomimo błędu var_dump wskazywał, że tablica jest tam dobrze (w obu przypadkach app i dev).
if (is_array($array))
wokół foreach ($array as $subarray)
rozwiązał problem.
Przepraszam, że nie mogę wyjaśnić przyczyny, ale ponieważ zajęło mi trochę czasu, aby znaleźć rozwiązanie, pomyślałem o lepiej podzielić się tym jako obserwacją.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-22 11:36:42
Użyję kombinacji empty, isset i is_array jako
$array = ['dog', 'cat', 'lion'];
if(!empty($array) && isset($array) && is_array($array){
//loop
foreach ($array as $values) {
echo $values;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-06 17:10:50
Użyj funkcji is_array, gdy przekażesz tablicę do pętli foreach.
if (is_array($your_variable)) {
foreach ($your_variable as $item) {
//your code
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-21 21:46:43
Warning invalid argument supplied for foreach () display tweets. przejdź do "/ wp-content / plugins / display-tweets-php". Następnie wstaw ten kod na linii numer 591, będzie działać idealnie.
if (is_array($tweets)){
foreach ( $tweets as $tweet )
{
...
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-03 02:59:48
Zrobiłbym to samo co Andy, ale użyłbym funkcji 'empty'.
Like so:
if(empty($yourArray))
{echo"<p>There's nothing in the array.....</p>";}
else
{
foreach ($yourArray as $current_array_item)
{
//do something with the current array item here
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-30 17:40:04