Introduction
Right after starting a project, Laravel provided us with a lot of useful features to design our system. However, there are still countless situations where only the available functions are not enough. To be able to extend those existing classes through inheritance, we will need to do many complicated steps. To solve the above problem, Laravel provides users with Macroable trait. In this article we will go into finding out:
- I. What is a Macroable Class
- II. How to use Macroable in Laravel
- III. Digging Deeper
I. What is a Macroable Class
Macroable is a trait in Laravel, classes that can be extended using Macros are called Macroable classes. Macros provides programmers with a simple method that allows us to extend an existing Laravel class with functions defined by themselves.
II. How to use Macroable in Laravel
1. How to use
To allow programmers to easily add methods to existing classes, Laravel provides two methods:
static void macro(string $name, object|callable $macro)
static void mixin(object $mixin, bool $replace = true)
a. Add a new function using a Macro
The macro()
allows us to register new functions for the Macroable Class. These functions will be written in the boot()
of ServiceProvider (eg AppServiceProvider). macro()
takes two input values of which: the first is the name of the register function, the second is a callback function that defines the function we want to register.
Example: Implementing to add prefix
function to the Support Str class of Laravel.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | namespace AppProviders; use ... class AppServiceProvider extends ServiceProvider { ... public function boot() { Str::macro('prefix', function ($string, $prefix) { return $prefix . $string; }); } ... } |
b. Add many new functions using Mixin
In case we have many functions we want to add, writing bulk of macro declarations in AppServiceProvider makes our ServiceProvider too big and managing editing becomes difficult. Instead, Laravel allows programmers to mix the functions of an Object into the Macroable Class using the mixin()
.
Similarly, macro()
we implement the declaration of mixin()
in the boot()
function of ServiceProvider. However, instead of passing the name and the corresponding callback function, we pass an object of the class we want to mix into the Macroable Class. Laravel will then perform the splitting of the methods and subscribe to the list of macros.
Example: Create and mix StrMixin class into Laravel Support Str class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | use ... class StrMixin { ... public function prefix($string, $prefix) { return $prefix . $string; } public function suffix($string, $suffix) { return $string . $suffix; } ... } # ===================================================== # Trong AppServiceProvider namespace AppProviders; use ... class AppServiceProvider extends ServiceProvider { ... public function boot() { Str::mixin(new StrMixin()); } ... } |
c. Handling duplicate functions
In the process of adding new functions, it is possible to generate duplicate macros in. By default, Laravel will override functions that are duplicated with the function we define. In case we don’t want to overwrite existing functions with the function in Mixin we can pass the boolean value to the second parameter replace .
For example:
1 2 | Str::mixin(new StrMixin(), false); |
2. Macroable Classes in Laravel
- Illuminate Auth RequestGuard
- Illuminate Auth SessionGuard
- Illuminate Cache Repository
- Illuminate Console Command
- Illuminate Console Scheduling Event
- Illuminate Cookie CookieJar
- Illuminate Database Eloquent FactoryBuilder
- Illuminate Database Eloquent Relations Relation
- Illuminate Database Grammar
- Illuminate Database Query Builder
- Illuminate Database Schema Blueprint
- Illuminate Filesystem Filesystem
- Illuminate Foundation Testing TestResponse
- Illuminate Http JsonResponse
- Illuminate Http RedirectResponse
- Illuminate Http Request
- Illuminate Http Response
- Illuminate Http UploadedFile
- Illuminate Mail Mailer
- Illuminate Routing PendingResourceRegistration
- Illuminate Routing Redirector
- Illuminate Routing ResponseFactory
- Illuminate Routing Route
- Illuminate Routing Router
- Illuminate Routing UrlGenerator
- Illuminate Support Arr
- Illuminate Support Collection
- Illuminate Support LazyCollection
- Illuminate Support Str
- Illuminate Support Testing Fakes NotificationFake
- Illuminate Translation Translator
- Illuminate Validation Rule
- Illuminate View Factory
- Illuminate View View
III. Digging Deeper
To easily add self-defined functions to an existing class, the above classes should use the IlluminateSupportTraitsMacroable
. Trait includes functions:
static void macro(string $name, object|callable $macro)
: Register the new macro.static void mixin(object $mixin, bool $replace = true)
: Mix an object into the class.static bool hasMacro(string $name)
: Check Macro register or not.static mixed __callStatic(string $method, array $parameters)
/static mixed __call(string $method, array $parameters)
: Call the Macro function to be registered.
Flow of operation:
- We perform the registration of a new function via
macro()
ormixin()
, the callback function is put into an array of staticmacros[]
. - When the programmer calls a function that does not exist, PHP will automatically pass the
__callStatic()
/__call()
. - Laravel checks that the function we call must be in the array of registered macros.
- If the function exists, the system calls the method dynamically and returns the result. Otherwise the system returns
BadMethodCallException
.
summary
So through the above article we have learned: what are macroable classes, how to use them in Laravel, classes can be extended using macros, and we also went into how they work. Thank you everyone for taking the time to read the above article. If you have any questions or suggestions, please comment below.
References
- Laravel API Document for Macroable trait: https://laravel.com/api/8.x/Illuminate/Support/Traits/Macroable.html
- CodersTape’s blog post for a Full list of Macroable classes: https://coderstape.com/blog/3-macroable-laravel-classes-full-list