Eloquent collections: each vs foreach
A foreach
statement should be used as a sort of a way to cycle through a collection and perform some sort of logic on it. If what is in it effects other things in the program, then use this loop.
The .each
method uses array_map
to cycle through each of the objects in the collection and perform a closure on each one. It then returns the resulting array. That is the key! .each
should be used if you want to change the collection in some way. Maybe it's an array of cars and you want to make the model upper case or lower case. You would just pass a closure to the .each
method that takes the object and calls strtoupper()
on the model of each Car object. It then returns the collection with the changes that have been made.
Morale of the story is this: use the .each
method to change each item in the array in some way; use the foreach
loop to use each object to affect some other part of the program (using some logic statement).
UPDATE (June 7, 2015)
As stated so Eloquently (see what I did there?) below, the above answer is slightly off. The .each
method using array_map
never actually used the output from the array_map
call. So, the new array created by array_map
would not be saved on the Collection
. To change it, you're better off using the .map
method, which also exists on a Collection
object.
Using a foreach
statement to iterate over each of them makes a bit more sense because you won't be able to access variables outside the Closure unless you make sure to use a use
statement, which seems awkward to me.
The implementation when the above answer was originally written can be found here.
.each
in Laravel 5.1
The new .each
that they are talking about below no longer uses array_map
. It simply iterates through each item in the collection and calls the passed in $callback
, passing it the item and its key in the array. Functionally, it seems to work the same. I believe using a foreach
loop would make more sense when reading the code. However, I see the benefits of using .each
because it allows you to chain methods together if that tickles your fancy. It also allows you to return false from the callback to leave the loop early if your business logic demands you to be able to.
For more info on the new implementation, check out the source code.
There is a lot of confusing misinformation in the existing answers.
The Short Answer
The short answer is: There is no major difference between using .each()
vs. foreach
to iterate over a Laravel collection. Both techniques achieve the same result.
What about modifying items?
Whether or not you're modifying items is irrelevant to whether you use .each()
vs. foreach
. They both do (and don't!) allow you to modify items in the collection depending on what type of items we're talking about.
-
Modifying items if the Collection contains objects: If the Collection is a set of PHP objects (such as an Eloquent Collection), either
.each()
orforeach
allow you to modify properties of the objects (such as$item->name = 'foo'
). That's simply because of how PHP objects always act like references. If you're trying to replace the entire object with a different object (a less common scenario), use.map()
instead. -
Modifying items if the Collection contains non-objects: This is less common, but if your Collection contains non-objects, such as strings,
.each()
doesn't give you a way to modify the values of the collection items. (The return value of the closure is ignored.) Use.map()
instead.
So... which one should I use?
In case you're wondering about performance, I did several tests with large collections of both Eloquent items and a collection of strings. In both cases, using foreach
was faster than .each()
. But we're talking about microseconds. In most real-life scenarios the speed difference wouldn't be significant compared to the time it takes to access the database, etc.
It mostly comes down to your personal preference. Using .each()
is nice because you can chain several operations together (for example .where(...).each(...)
). I tend to use both in my own code just depending on what seems the cleanest for each situation.
Contrary to what the two other answers say, Collection::each()
does not change the values of the items in the Collection, technically speaking. It does use array_map()
, but it doesn't store the result of that call.
If you want to modify each item in a collection (such as to cast them to objects as Damon in a comment to the crrently accepted answer), then you should use Collection::map()
. This will create a new Collection based on the result of the underlying call to array_map()
.