Ce n'est peut-être pas une question spécifique aux collections Eloquent, mais cela m’a frappé tout en travaillant avec elles. Supposons simplement que nous avons un objet $collection
qui est une instance de Illuminate\Support\Collection
.
Maintenant, si nous voulons parcourir le sujet, quels sont les avantages et les inconvénients d’utiliser each()
avec une fermeture par rapport à un foreach
régulier. Y a-t-il?
foreach ($collection as $item) {
// Some code
}
--- VS ---
$collection->each(function ($item) {
// Some code
});
Une instruction foreach
doit être utilisée comme une sorte de moyen de parcourir une collection et d’exécuter une sorte de logique dessus. Si son contenu affecte d'autres éléments du programme, utilisez cette boucle.
La méthode .each
utilise array_map
pour parcourir chacun des objets de la collection et effectuer une fermeture sur chacun d'eux. Il retourne ensuite le tableau résultant. C'est la clé! .each
doit être utilisé si vous souhaitez modifier la collection d’une manière ou d’une autre. Peut-être que c'est un éventail de voitures et que vous voulez faire le modèle majuscule ou minuscule. Vous ne feriez que passer une fermeture à la méthode .each
qui prend l'objet et appelle strtoupper()
sur le modèle de chaque objet Car. Il retourne ensuite la collection avec les modifications apportées.
Le moral de l'histoire est le suivant: utilisez la méthode .each
pour modifier chaque élément du tableau d'une manière ou d'une autre; utilisez la boucle foreach
pour utiliser chaque objet afin d'affecter une autre partie du programme (à l'aide d'une instruction logique).
Comme indiqué de manière éloquente (voir ce que j'ai fait ici?) Ci-dessous, la réponse ci-dessus est légèrement erronée. La méthode .each
utilisant array_map
n'a jamais réellement utilisé la sortie de l'appel array_map
. Ainsi, le nouveau tableau créé par array_map
ne sera pas enregistré sur la Collection
. Pour le changer, il vaut mieux utiliser la méthode .map
, qui existe également sur un objet Collection
.
Utiliser une instruction foreach
pour parcourir chacune d'elles est un peu plus logique car vous ne pourrez pas accéder à des variables en dehors de la fermeture à moins de vous assurer d'utiliser une instruction use
, ce qui me semble difficile.
L'implémentation lorsque la réponse ci-dessus a été écrite à l'origine peut être trouvée ici .
.each
dans Laravel 5.1Le nouveau .each
dont il est question ci-dessous n’utilise plus array_map
. Il itère simplement à travers chaque élément de la collection et appelle le passé dans $callback
, en lui passant l'élément et sa clé dans le tableau. Fonctionnellement, cela semble fonctionner de la même manière. Je pense qu’utiliser une boucle foreach
donnerait plus de sens à la lecture du code. Cependant, je vois les avantages de l’utilisation de .each
car il vous permet d’enchaîner des méthodes si cela chatouille votre fantaisie. Il vous permet également de renvoyer faux à partir du rappel afin de quitter la boucle plus tôt si votre logique d’entreprise vous le demande.
Pour plus d'informations sur la nouvelle implémentation, consultez le code source .
Il y a beaucoup de désinformation déroutante dans les réponses existantes.
La réponse courte est la suivante: Il n'y a pas de différence majeure entre l'utilisation de .each()
et foreach
pour parcourir une collection de Laravel. Les deux techniques donnent le même résultat.
Que vous modifiiez ou non des éléments n'a pas d'importance si vous utilisez .each()
contre foreach
. Ils permettent (et non!) De modifier les éléments de la collection en fonction du type d’éléments dont nous parlons.
.each()
ou foreach
vous permet de modifier les propriétés des objets (tels que $item->name = 'foo'
) . C'est simplement à cause de la façon dont les objets PHP agissent toujours comme des références. Si vous essayez de remplacer l'objet entier par un objet différent (un scénario moins courant), utilisez plutôt .map()
..each()
ne vous permet pas de modifier les valeurs des éléments de la collection. (La valeur de retour de la fermeture est ignorée.) Utilisez plutôt .map()
.Au cas où vous vous interrogeriez sur les performances, j'ai fait plusieurs tests avec de grandes collections d'éléments Eloquent et une collection de chaînes. Dans les deux cas, utiliser foreach
était plus rapide que .each()
. Mais nous parlons de microsecondes. Dans la plupart des scénarios réels, la différence de vitesse ne serait pas significative par rapport au temps nécessaire pour accéder à la base de données, etc.
Cela dépend principalement de vos préférences personnelles. Utiliser .each()
est agréable car vous pouvez chaîner plusieurs opérations ensemble (par exemple .where(...).each(...)
). J'ai tendance à utiliser les deux dans mon propre code, en fonction de ce qui semble le plus propre pour chaque situation.
Contrairement à ce que disent les deux autres réponses, Collection::each()
ne modifie pas pas techniquement les valeurs des éléments de la collection. Il utilise array_map()
, mais il ne stocke pas le résultat de cet appel.
Si vous souhaitez modifier chaque élément d'une collection (pour les attribuer à des objets tels que Damon dans un commentaire sur la réponse réellement acceptée), utilisez Collection::map()
. Cela créera une nouvelle collection en fonction du résultat de l'appel sous-jacent à array_map()
.
Il est plus avantageux d’utiliser ce dernier: each ().
Vous pouvez chaîner des conditions et écrire un code plus clair et plus expressif, par exemple:
$ exemple-> chaque () -> map () -> filter ();
Cela vous rapproche de la programmation déclarative, dans laquelle vous indiquez à l'ordinateur ce qu'il doit accomplir plutôt que comment.
Quelques articles utiles: