Ever wanted a piece of functionality in a part of Laravel that doesn’t exist? Let me introduce you to Laravel macros. Macros allow you to add on custom functionality to internal Laravel components.
Let’s start with a simple example on the Request
facade.
php
Request::macro('introduce', function ($name) { echo 'Hello ' . $name . '!';}); Request::introduce('Caleb'); // outputs "Hello Caleb!"
A more practical example of a Request
macro would be detecting the current TLD (Top Level Domain: .com, .net, .org, etc…).
Request::macro('tldIs', function ($tld) { return Str::is('*.' . $tld, $this->root());}); Request::tldIs('com') // returns true for app.comRequest::tldIs('dev') // returns false for app.com
You’ll notice Laravel automatically binds $this
to the context of Request
rather than the class where the macro is defined. For example:
class AppServiceProvider{ public function boot() { Request::macro('context', function () { return get_class($this); } }... Request::context();// returns 'Illuminate\Http\Request'// instead of 'App\AppServiceProvider'
Let’s look at a more advanced example. This macro conditionally adds a where
statement on the model based on the current TLD.
Builder::macro('whenTldMatches', function($tld, $callback) { if (Request::tldIs($tld)) { call_user_func($callback->bindTo($this)); } return $this;}); SomeModel::whenTldMatches('org', function () { $this->where('id', '>', 5);})->get(); // applies ->where() on app.org but not app.com
Service providers are a great place to define macros for your app. App\Providers\AppServiceProvider
boot()
is a good starting point, but can quickly become bloated. The next step is to create a App\Providers\MacrosServiceProvider
and register it in config/app.php
. If certain macros are related, such as the examples above, I might create a App\Providers\TldAwareServiceProvider
to house all TLD related macros.
Macros can be defined on any class with the Macroable
trait. Below is a list of Macroable facades & classes:
Facades
Illuminate Classes
If you find yourself repeating performing logic on Laravel components throughout your system, think about using a macro for better expression and reuse. Trust me, they’re addicting.
Good Luck!
We appreciate your interest.
We will get right back to you.