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 unif
- autre (veuillez suggérer)
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.
et celui-ci? beaucoup plus propre et le tout en une seule ligne.
foreach ((array) $items as $item) {
// ...
}
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
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:
- Rapide vérification de type :
$array = is_array($var) or is_object($var) ? $var : [] ;
- type indiquant les tableaux dans les méthodes avant d'utiliser un foreach et spécifiant les types de retour
- enveloppant foreach à l'intérieur de if
- utilisant
try{}catch(){}
blocs - conception du code / essai approprié avant la sortie de la production
- 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 !) . - toujours extraire vos méthodes helper dans l'espace de noms global d'une manière à réduire le code dupliqué
essayez ceci:
//Force array
$dataArr = is_array($dataArr) ? $dataArr : array($dataArr);
foreach ($dataArr as $val) {
echo $val;
}
;)
$values = get_values();
foreach ((array) $values as $value){
...
}
problème est toujours nul et le moulage est en fait la solution de nettoyage.
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.
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; ?>
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.
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;
}
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.
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!!!
}
}
Que pensez-vous de cette solution:
$type = gettype($your_iteratable);
$types = array(
'array',
'object'
);
if (in_array($type, $types)) {
// foreach code comes here
}
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.
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;
}
}
utilisez la fonction is_array, lorsque vous passerez le tableau à chaque boucle.
if (is_array($your_variable)) {
foreach ($your_variable as $item) {
//your code
}
}
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 )
{
...
}
}
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
}
}