Confession time - I'm writing a "book". Yes, me too. Actually, I call it an "ePamphlet", as it will only be about 8-10 pages, completely FREE, and written very narrowly about the Laravel Collection class. Laravel Collections Unraveled is just a deep dive into the class that I thought was too long for a blog post, and could be best presented via a LeanPub eBook. We'll dig into the source code of this popular class and see some use cases for the major functions. Sign up to find out when it's ready - it's a nice motivator to know people are looking forward to getting a copy. The following is completely fresh material, but a sample of some of the stuff I look at in the book.

Ever been looping over an array and needed to know in advance what the next item was? I'm sure we all have our little tricks...$currentRow, $prevRow...oh, no. PHP itself actually has a couple of iterator classes that make this much simpler, and of course Laravel's Collection class has an implementation that is as easy to use as you've grown to expect.

The two classes we'll be working with under the hood are the PHP core classes ArrayIterator and CachingIterator, called from the Collection itself as getIterator() and getCachingIterator(). As you can see by looking at the manual for CachingIterator, it takes an ArrayIterator in its __construct. (Technically any Iterator, but humor me.) Laravel sets this all up for you in the getCachingIterator() method, first creating an iterator from your collection and then passing it into the new CachingIterator. Therefore, you only have to write:

$collection = collect([1=>11, 5=>13, 12=>14, 21=>15])->getCachingIterator();

to get an instance of CachingIterator to work with.

Now the cool part. You can see I intentionally set up the array to be a little "ugly" - no fair cheating by trying to just increment the keys! Instead, if you wanted to output something that showed the current and next values together, you would have to do the old trick of storing the first value in a variable, setting a flag, then starting the output in the next loop iteration. I'm not going to write it - you've been there before. What you are doing, of course, is just a poor man's cache. So instead, how about this?

foreach ($collection as $key => $value) { dump($collection->current() . ':' . $collection->getInnerIterator()->current()); }

Run that and see what you get. Pretty awesome, eh?

What's actually happening is slightly confusing, but realize the $collection refers to the outer, CachingIterator, which starts empty (it's a cache, and nothing has been put there yet). The inner iterator is just an ArrayIterator. Each time it is called, it passes its value out to the cache. Therefore, the CachingIterator always seems to be "one behind" its inner object.

PHP Iterator classes are actually pretty amazing, and I think underutilized by most of us used to just working with frameworks most of our day. I highly recommend playing with them from time to time and seeing all their uses.

Hope that helps!