What good Laravel Macros bring?
Have you ever been in a situation that you wanted a method or functionality to be part of Laravel’s core, but for one or another reason it isn’t? I get this feeling a lot, especially when writing tests and working with collections. It’s not possible to have everything one needs in a tool or a framework like Laravel. There will always be the need for our own utilities and abstractions to better solve some project-specific problems.
Macros are there to help us exactly with these situations. With Macros we can extend the power of Laravel’s components/classes in a very easy, clean and expressive way.
In the below example, we will add a method named
evens() to the Laravel’s Collection class, this method will return only even numbers in an array.
Collection::macro is bound to the instance of
Illuminate\Support\Collection class. This will help more with our code’s expresiveness by providing more context inside
macro(), we will be able to use lots of existing methods on that class. Remember,
$this always binds to the instance of the class we are creating Macro for.
Where to define them?
As Macros are added in the runtime, therefore the best place to define them are inside Laravel’s Service Providers. This will make sure that our newly added methods will be available nearly everywhere in our code. We can add them in the
AppServiceProvider as shown in the below example or inside a more specific service provider that we may wanna create for this purpose.
How to know if a component is macro-able?
There are around 20 classes in Laravel which are macro-able. If a class is using
Illuminate\Support\Traits\Macroable trait, it’s “Macroable”. See the
Illuminate\Support\Arr class as an example:
Some Practical Examples
In one of my projects, I added some utility assertion methods (Macros) for
Illuminate\Foundation\Testing\TestResponse class to have some expressive and clean assertions.
Using these assertions I can do:
Of course, I used above example to describe the concept easily. Macros can be used to simplify much more complicated logic. You can find a more advanced example in below. There are 4 macro examples, you can go through each one of them to understand what they actually do.
That’s it. Thank you for reading this. Let me know if you have any questions or comments in below.