Argument non valable fourni pour foreach()

il m'arrive souvent de traiter des données qui peuvent être soit un tableau ou une variable nulle et d'alimenter quelques foreach avec ces données.

$values = get_values();

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

quand vous alimentez un foreach avec des données qui ne sont pas un tableau, vous recevez un avertissement:

avertissement: argument invalide fourni pour foreach () dans [...]

en supposant qu'il n'est pas possible de reformuler la fonction get_values() pour toujours retourner un tableau (rétrocompatibilité, code source non disponible, quelle que soit la raison), je me demande Quel est le moyen le plus propre et le plus efficace pour éviter ces avertissements:

  • Casting $values array
  • initialisant $values à array
  • enveloppant le foreach avec un if
  • autre (veuillez suggérer)
248
demandé sur Geoffrey Hale 2010-04-13 17:48:46

18 réponses

Personnellement, je trouve cela plus propre - ne sais pas si c'est le plus efficace, de l'esprit!

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

la raison de ma préférence est qu'il n'alloue pas un tableau vide quand vous n'avez rien à commencer par quoi que ce soit.

424
répondu Andy Shellam 2015-10-27 20:57:40

et celui-ci? beaucoup plus propre et le tout en une seule ligne.

foreach ((array) $items as $item) {
 // ...
 }
76
répondu Ajith R Nair 2015-04-08 17:08:27

j'utilise habituellement une construction semblable à celle-ci:

/**
 * 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...
    }
}

notez que cette version particulière n'est pas testée, elle est tapée directement dans SO à partir de la mémoire.

Edit: , a ajouté Traversable vérifier

37
répondu Kris 2015-05-25 13:47:49

s'il vous Plaît ne dépend pas de casting comme une solution , même si d'autres suggèrent que c'est une option valide pour prévenir une erreur, cela pourrait en causer une autre.

soyez conscient: si vous vous attendez à ce qu'une forme spécifique de tableau soit retournée, cela pourrait vous faire défaut. Plusieurs vérifications sont nécessaires pour cela.

E. G. casting un booléen à un tableau (array)bool , will NOT résulte en un tableau vide, mais un tableau avec un élément contenant la valeur booléenne comme int: [0=>0] ou [0=>1] .

j'ai écrit un test rapide pour présenter ce problème . (Voici un backup Test au cas où la première url de test échoue.)

Inclus sont des tests pour: null , false , true , un class , un array et undefined .


Testez toujours votre entrée avant de l'utiliser dans foreach. Suggestions:

  1. Rapide vérification de type : $array = is_array($var) or is_object($var) ? $var : [] ;
  2. type indiquant les tableaux dans les méthodes avant d'utiliser un foreach et spécifiant les types de retour
  3. enveloppant foreach à l'intérieur de if
  4. utilisant try{}catch(){} blocs
  5. conception du code / essai approprié avant la sortie de la production
  6. pour tester un tableau par rapport à la bonne forme vous pouvez utiliser array_key_exists sur une clé spécifique, ou tester la profondeur d'un tableau (quand il est un !) .
  7. toujours extraire vos méthodes helper dans l'espace de noms global d'une manière à réduire le code dupliqué
13
répondu AARTT 2017-05-23 12:10:54

essayez ceci:

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

;)

6
répondu GigolNet Guigolachvili 2018-07-30 12:52:18
$values = get_values();

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

problème est toujours nul et le moulage est en fait la solution de nettoyage.

4
répondu boctulus 2016-03-02 16:59:44

tout d'Abord, chaque variable doit être initialisée. Toujours.

Casting n'est pas une option.

si get_values (); peut retourner une variable de type différente, cette valeur doit être cochée, bien sûr.

3
répondu Your Common Sense 2010-04-13 14:11:25

extension plus concise de @Kris's code

function secure_iterable($var)
{
    return is_iterable($var) ? $var : array();
}

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

spécialement pour l'utilisation du code de modèle intérieur

<?php foreach (secure_iterable($values) as $value): ?>
    ...
<?php endforeach; ?>
3
répondu HongKilDong 2017-05-23 11:33:24
foreach ($arr ? $arr : [] as $elem) {
    // Does something 
}

ceci ne vérifie pas si c'est un tableau, mais saute la boucle si la variable est nulle ou un tableau vide.

2
répondu T30 2016-07-14 02:41:50

si vous utilisez php7 et que vous voulez traiter seulement les erreurs non définies, c'est le plus propre IMHO

$array = [1,2,3,4];
foreach ( $array ?? [] as $item ) {
  echo $item;
}
2
répondu Edwin Rodríguez 2016-08-09 15:27:03

Je ne suis pas sûr que ce soit le cas, mais ce problème semble se produire à plusieurs reprises lors de la migration de sites wordpress ou de la migration de sites dynamiques en général. Si c'est le cas, assurez-vous que l'hébergement que vous migrez utilise la même version PHP que celle utilisée par votre ancien site.

si vous n'êtes pas en train de migrer votre site et que ce n'est qu'un problème qui est apparu, essayez la mise à jour vers PHP 5. Cela prend en charge certains de ces problèmes. Peut sembler comme une solution stupide, mais a fait le truc pour moi.

1
répondu Erik 2014-07-12 13:16:28

cas exceptionnel pour cet avis se produit si vous définissez array à null inside foreach loop

if (is_array($values))
{
    foreach ($values as $value)
    {
        $values = null;//WARNING!!!
    }
}
1
répondu Farid Movsumov 2016-01-18 09:24:52

Que pensez-vous de cette solution:

$type = gettype($your_iteratable);
$types = array(
    'array',
    'object'
);

if (in_array($type, $types)) {
    // foreach code comes here
}
1
répondu Julian 2017-11-01 12:04:11

il semble y avoir aussi une relation avec l'environnement:

j'ai eu cet" argument invalide fourni foreach () " erreur seulement dans l'environnement dev, mais pas dans prod (je travaille sur le serveur, pas localhost).

malgré l'erreur un var_dump a indiqué que le tableau était bien là (dans les deux cas app et dev).

le if (is_array($array)) autour du foreach ($array as $subarray) a résolu le problème.

désolé, que je Je ne peux pas expliquer la cause, mais comme il m'a fallu un certain temps pour trouver une solution, j'ai pensé à mieux partager ceci comme une observation.

0
répondu araldh 2015-02-22 11:36:42

je vais utiliser une combinaison de vide, isset et is_array comme

$array = ['dog', 'cat',  'lion'];

if(!empty($array)  && isset($array)  && is_array($array){
//loop
foreach ($array as $values) {
echo $values; 
}
}
0
répondu Akintunde-Rotimi 2017-10-06 17:10:50

utilisez la fonction is_array, lorsque vous passerez le tableau à chaque boucle.

if (is_array($your_variable)) {
  foreach ($your_variable as $item) {
   //your code
}
}
0
répondu Super Model 2017-10-21 21:46:43

avertissement argument invalide fourni pour foreach() afficher les tweets. allez dans " /wp-content/plugins/affichage de tweets-php ". Puis insérez ce code sur la ligne numéro 591, il fonctionnera parfaitement.

if (is_array($tweets)){  
        foreach ( $tweets as $tweet ) 
    {
        ...
    }
}
0
répondu Saad Khanani 2018-05-03 02:59:48

je ferais la même chose Qu'Andy, mais j'utiliserais la fonction "vide".

comme suit:

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
  } 
}
-3
répondu as_bold_as_love 2012-09-30 17:40:04