Collections in PHP

A while ago I stumbled on Adam Wathans book "Refactoring to Collections" and a lot of people saying this is a really great book. Of course I didn't get it at the time: collections were a thing I had never given a lot of thought. Ok, now that some time had passed I read another blogpost by Christoph Rumpel on the topic and eventually commited to find out what's up with this thing that people think is so great. Long story short: I researched a bit, got the book and then I realized some hours had passed. Not bad for a programming-book...

What are Collections?

This was the question I started out with since I head never had much contact with the concept of a collection. To put it short: a collection is an object that implements all the interactions you can have with a normal array but also provides a lot of additional functionallity. Hence the common description as "arrays in steroids".

Since I am a Laravel user anyways and find the things Taylor writes very intuitive to use, I am using his Collection class even when working outside Laravel and also for these examples. So let's start with the most basic thing: How does one create a collection?

There is a nice helper function that returns a Collection Object, so you can use it like this: $collection = collect(['item 1', 'item 2']); Just pass an array, no matter if it's as simple as this one or some large complicated multidimensional construct:

<?php

$items = [
    'bread' => ['amount' => 2, 'price' => 4.99],
    'butter' => ['amount' => 1, 'price' => 6.99],
];

$shoppingList = collect($shoppingList);

If you now want to access this collection, you can do this as with any regular array if you want, e.g. $shoppingList['bread']['price'], but of course that's not why we are doing this.

What can I do with a collection?

That was of course the question I asked myself annd upon reading Adams book and having a look through Taylors documentation for the Collection class I have to say that the additional features compared to normal arrays are really quite a great thing to have.

For example, let's find out what we would have to pay for our shopping list:

<?php

$items = [
    'bread' => ['amount' => 2, 'price' => 4.99],
    'butter' => ['amount' => 1, 'price' => 6.99],
];

$price = collect($items)->map(function($item) {
    return $item['amount'] * $item['price'];
})->sum();

What this is doing is to create a collection of items (collect()), map each of them to the value for the money spent on that item and then return the sum of those values. Let's have a look at what I would have done before:

<?php

$items = [
    'bread' => ['amount' => 2, 'price' => 4.99],
    'butter' => ['amount' => 1, 'price' => 6.99],
];

$price = 0;

foreach($items as $item) {  
    $price += $item['price'] * $item['price'];
};

So yes: there are more then enough reasons not to want to go back. And this is a rather simplistic example, so the way I see it right now the collection would shine even more in a more complex situation where we would normally have nested loops and can get rid of those.

  • The new code looks way more readable then the "old" code.
  • No need to manually deal with implementation details like having a variable thats counted up.
  • No writing loops. We write enough of those as it is.

So long story short: I will continue to get on peoples nerves with this and most likely show some more interesting example after really having worked with this a while.