Laravel 5 Macros: Creating Class Based Macros with Mixins

April 21, 2018 —John Koster

In version 5.4, Laravel added the concept of "macro mixins": a way to define and group related macro methods and utility functions into a class and then inject, or mix in all of the class methods as macro methods to any class that utilizes the Illuminate\Support\Traits\Macroable trait.

Let's first examine the method of adding macros to classes before mixins were available. In the following example we are adding a new macro method soundex to the Illuminate\Support\Str class:

1use Illuminate\Support\Str;
2 
3Str::macro('soundex', function ($str) {
4 return soundex($str);
5});

We can accomplish the same thing using mixin classes by first creating a class and then implementing the macro methods within the class:

1class StringMixin
2{
3 
4 // |---> This will be the macro name.
5 // |
6 public function soundex()
7 {
8 // The function returned by the mixin instance
9 // method is what will be invoked when a user
10 // calls our macro method on the target class.
11 return function ($str) {
12 return soundex($str);
13 };
14 }
15 
16}

One peculiar thing to take note of is that when use mixin classes, we need to return the callback function that will be invoked when a user calls our macro method. The name of the class method that is returning the callback function is the name that will be given to our macro.

Mixin classes are not automatically injected into classes at run-time, we need to inform the target class (the class that utilizes the Illuminate\Support\Traits\Macroable) trait to load the methods from our mixin class and use them as macro methods. We can do this using the mixin method.

The mixin method is used to inform a class that it should load the instance methods from a mixin class as macro methods. The mixin method takes a class instance as its first and only argument. We could add our StringMixin class to the Str class like so:

1use Illuminate\Support\Str;
2 
3// Add our string mixins to the Str class.
4Str::mixin(new StringMixin);
5 
6// We now have access to the `soundex` mixin:
7$value = Str::soundex('stringValue');

Some absolutely amazing
people

The following amazing people help support this site and my open source projects ♥️
If you're interesting in supporting my work and want to show up on this list, check out my GitHub Sponsors Profile.