Datadog collects and monitors your PHP app metrics and distributed traces in real-time with application performance monitoring. Decrease downtime and performance issues with Datadog APM by tracing requests across service boundaries and drilling into individual traces end-to-end with flame graphs. Start your 14-day trial for free today.

Debugging collections

Original – by Freek Van der Herten – 3 minute read

Lately I've been working a lot with collections in Laravel. If you're not in the know: a collection is a sort of super charged array with a lot of powerful functions to transform the data inside it. The only thing I found a bit of a hassle is how to debug the various steps in a collection chain. Here's how I improved the workflow.

Using a collection class you can build up a chain of functions to transform data. Take a look at this example (I left out the function bodies to make it a bit shorter).

collect($items)
  ->filter(function() { 
     ... 
   })
   ->unique(function() { 
      ... 
   })
   ->map(function() {
     ... 
   })
   ->sortBy(function() { 
      ...
   });

Image you are debugging this code. You want to see what the values are after the map function. To do that you could wrap the code starting from the collection call until right after the map function in a dd function.

dd(collect($items)
  ->filter(function() { 
     ... 
   })
   ->unique(function() { 
      ... 
   })
   ->map(function() {
     ... 
   }))
   ->sortBy(function() { 
      ...
   });

Sure enough, the contents of the collection after the map function will get dumped to the screen. But there's some work involved: you have to insert code a the beginning of the collection and an extra closing parenthesis after the map function. To my eyes this isn't very readable. It's also a bit of a hassle to remove the dd statement, that closing parenthesis is easily forgotten. I'm exaggerating the problems a bit, but I can assure you'll get tired of debugging like this really quick. There must be a better way.

Laravel's collection class is Macroable. That means we can add functions to the class at runtime. To improve our debugging workflow let's create a simple dd macro:

Collection::macro('dd', function () {
    dd($this);
});

To use the macro anywhere in a project you could place it a ServiceProvider. Take a look Blender, our Laravel template, for an example.

Using the macro debugging a collection becomes much simpler. Here's how to use it:

collect($items)
  ->filter(function() { 
     ... 
   })
   ->unique(function() { 
      ... 
   })
   ->map(function() {
     ... 
   })
   ->dd()
   ->sortBy(function() { 
      ...
   });

To see the values after a particular step in the chain you simply have to add one line of code. It's perfectly readable. After you've done your debugging there's only one line to remove. Using PHPStorm's alt+shift+arrow-up and alt+shift+arrow-down shortcuts the ->dd() line can be easily moved to the previous or next part of the collection chain.

You can learn more about collections in Laravel's official documentation and Adam Wathan's excellent book on the subject.

Stay up to date with all things Laravel, PHP, and JavaScript.

Follow me on Twitter. I regularly tweet out programming tips, and what I myself have learned in ongoing projects.

Every two weeks I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.

Comments