Refactor related macros to classes using Mixins in Laravel
In one of my articles, I’ve described how you can add different behavior to some of the classes in Laravel using macros. To give you a primer, Laravel ships with this trait called Illuminate\Support\Traits\Macroable using which you can add additional methods to the class in hand (which is using the Macroable
trait) at run time.
You may also like: Extending class behaviour in Laravel using Macros
For instance, we’ve got Illuminate\Support\Str
class in Laravel which is a “macroable” class. And if you want to add an additional method which doesn’t exist in the class currently, you can do it like so.
namespace App\Providers;
use Illuminate\Support\Str;
class AppServiceProvider
{
public function boot()
{
Str::macro('makeInvoiceId', function ($value) {
return 'INVOICE-'.$value;
});
}
}
Now, you can call this method on the Illuminate\Support\Str
just like a class’ native method like so.
$invoiceId = Str::makeInvoiceId('87475867');
// INVOICE-87475867
You can go on making different macros in your AppServiceProvider
’s boot
method. But one thing to note here is when you tend to define many (but related) macro methods, your boot
method can quickly get bloated. For instance, let’s say you want to add two more such methods on the Illuminate\Support\Str
class coupled with macros for other classes as well, you can imagine where we are going.
This can be solved by using macro mixins.
What is mixin
?
The Illuminate\Support\Traits\Macroable
contains a method named mixin
which can be used to refactor related macros to a dedicated class.
For instance, if we want to move the Illuminate\Support\Str
’s mixin class by creating an app/Mixins
directory like so.
namespace App\Mixins;
class StrMacros
{
public function makeInvoiceId()
{
return function ($value) {
return 'INVOICE-'.$value;
}
}
}
As you can see, StrMacros
is just a simple PHP class and here, you can create as many macro methods as you may like which will act as methods just like you’d be creating using the macro
method. Note also that, the function returns a closure, similarly how you’d pass to the macro
method. Notice also that the makeInvoiceId
doesn’t receive any parameter at all. Instead, the closure inside is receiving the parameter. That’s some kind of magic!
Now, to use this all you need to do is pass in this class to call the mixin
method on the Illuminate\Support\Str
class like so.
namespace App\Providers;
use Illuminate\Support\Str;
use App\Mixins\StrMacros;
class AppServiceProvider
{
public function boot()
{
Str::mixin(new StrMacros);
}
}
You can create many such macros for classes that are Macroable
and group related macros.
And there you have it. Your macros refactored nicely to a separate class which is far better and elegant than bloating the AppServiceProvider
with scattered standalone macros.
Like this article?
Buy me a coffee👋 Hi there! I'm Amit. I write articles about all things web development. You can become a sponsor on my blog to help me continue my writing journey and get your brand in front of thousands of eyes.