web-dev-qa-db-fra.com

while (list ($ key, $ value) = each ($ array)) vs foreach ($ array as $ key => $ value)?

Récemment, j'ai rencontré ce problème étrange:

while(list($key, $value) = each($array))

ne répertoriait pas toutes les valeurs du tableau, où le remplacer par ...

foreach($array as $key => $value)

... a parfaitement fonctionné.

Et, je suis curieux maintenant .. quelle est la différence entre ces deux?

35
jolt

Avez-vous déjà parcouru le tableau? each() se souvient de sa position dans le tableau, donc si vous ne le faites pas reset() vous pouvez manquer des éléments.

reset($array);
while(list($key, $value) = each($array))

Pour ce que ça vaut, cette méthode de traversée de tableaux est ancienne et a été remplacée par la foreach plus idiomatique. Je ne l'utiliserais pas à moins que vous ne souhaitiez spécifiquement profiter de sa nature un élément à la fois.

tableau chacun ( tableau & $ tableau)

Retourne la paire clé/valeur actuelle d'un tableau et avance le curseur du tableau.

Après l'exécution de each(), le curseur du tableau sera laissé sur l'élément suivant du tableau, ou passé le dernier élément s'il atteint la fin du tableau. Vous devez utiliser reset() si vous voulez parcourir à nouveau le tableau en utilisant each.

(Source: Manuel PHP )

53
John Kugelman

Eh bien, une différence est que each() ne fonctionnera que sur les tableaux (enfin ne fonctionnera correctement). foreach fonctionnera sur tout objet qui implémente l'interface traversable (qui inclut bien sûr le type de tableau intégré).

Il peut y avoir une micro-optimisation dans le foreach. Fondamentalement, foreach équivaut à ce qui suit:

$array->rewind();
while ($array->valid()) {
   $key = $array->key();
   $value = $array->current();
   // Do your code here
   $array->next();
}

Alors que each fait essentiellement ce qui suit:

$return = $array->valid() ? array($array->key(), $array->current()) : false;
$array->next();
return $return;

Donc, trois lignes sont identiques pour les deux. Ils sont tous deux très similaires. Il peut y avoir quelques micro-optimisations dans la mesure où each n'a pas besoin de se soucier de l'interface traversable ... Mais cela va être au mieux mineur. Mais cela va aussi être compensé en faisant le cast booléen et en archivant le code php vs le C compilé par foreach ... Sans oublier que dans votre while/each code, vous appelez deux constructions de langage et une fonction, alors qu'avec foreach c'est une construction de langage unique ...

Sans oublier que foreach est BEAUCOUP plus lisible à mon humble avis ... Donc, plus facile à lire et plus flexible signifie que -à moi- foreach est clairement le gagnant. (cela ne veut pas dire que each n'a pas son utilité, mais personnellement je n'en ai jamais eu besoin) ...

13
ircmaxell

Attention! Foreach crée une copie du tableau afin que vous ne puissiez pas le modifier pendant que foreach l'itère. each() a toujours un but et peut être très utile si vous effectuez des modifications en direct sur un tableau tout en bouclant sur ses éléments et index.

// Foreach creates a copy
$array = [
  "foo" => ['bar', 'baz'],
  "bar" => ['foo'],
  "baz" => ['bar'],
  "batz" => ['end']
];

// while(list($i, $value) = each($array)) { // Try this next
foreach($array as $i => $value) {
  print $i . "\n";
  foreach($value as $index) {
    unset($array[$index]);
  }
}

print_r($array); // array('baz' => ['end'])

foreach et while termineront leurs boucles et le tableau "$array" Sera modifié. Cependant, la boucle foreach n'a pas changé pendant qu'elle était en boucle - elle a donc toujours itéré sur chaque élément même si nous les avions supprimés.

Mise à jour: Cette réponse n'est pas une erreur.

Je pensais que cette réponse était assez simple, mais il semble que la majorité des utilisateurs ici ne soient pas en mesure d'apprécier les détails spécifiques que je mentionne ici.

Les développeurs qui ont construit des applications en utilisant libdom (comme la suppression d'éléments) ou d'autres filtrages intensifs de cartes/listes/dict peuvent attester de l'importance de ce que j'ai dit ici.

Si vous ne comprenez pas cette réponse, elle vous mordra un jour.

9
Xeoncross

Si vous avez passé each un objet à parcourir, le manuel PHP prévient qu'il peut avoir des résultats inattendus.

Que contient exactement $array

1
Dan McGrath