The Magical use of Macroables in Laravel

If you've no idea what macroable functionality is, take it as something you want to extend in within Laravel with a piece of code that doesn't exists in the Class.

What is Macroable ?

If you’ve no idea what macroable functionality is, take it as something you want to extend in within Laravel with a piece of code that doesn’t exists in the Class. In short, Macros allow you to add custom functionality to internal Laravel components.

For instance, Laravel has by default Iluminate/Support/Str helper Class which contains most of the String helper functions like upper, lower, title etc.

Now you need to append some value or a symbol to a string. But there’s no helper function for that. What would you do? Well There’re a number of ways.

Traditional Way

The traditional object-oriented way would be to create another Class which then extends Iluminate/Support/Str & define your custom helper method inside it. Likeso

class MoreStrFunctions extends Str {
   public function appendsTo( $str, $param  ) {
      return $str. $param;
   }
}

And calling it like: (new MoreStrFunctions)->appendsTo(); quite messy right?

Magical Way

Or the other way around is to create a simple macro where you extends the Class but without actually extending the Class. Confused? Defining and calling macros are as simple as you ask for.

Defining a Macro

The very first step is to define your macro, but the most important pre-requisite of defining a macro is to make sure if the Class is Macroable or in simpler words if the Class is extending Macroable trait. For now we’re defining it inside of boot() method of AppServiceProvider. That would work for now.

Str::macro('appendsTo',function($str, $param){
   return $str. $param;
});

Calling a Macro

Once the macro is defined, we can call it anywhere within the Laravel application likeso.

Str::appendsTo('thewebtier','_');

Handling Multiple Macros

If you need to define multiple macros for a Macroable Class. Including these in one single file or inside boot() method of a ServiceProvider may look pretty messy pretty quickly. To fix this issue, Laravel ships in within their macro functionality called Mixins.

You can create a separate Class containing all of those macros & to use this class, we’ll utilise Mixins to initiate our macros.

Str::mixin(new Macros/StrMacros);

For time being, you may place this piece of code inside boot() method of AppServiceProvider.

Now inside of our StrMacros Class, we may define as many custom macros as we like to.

class StrMacros {

   public function appendsTo(  ) {
      return function($str,$param){
            return $str.$param;
      };
   }

}

We can also bind other helper functions from Str Class here. For example we would like the output string to be all upper case.

   public function appendsTo(  ) {
      return function($str,$param){
            return static::upper($str) .$param;
      };
   }

Another cool magic of defining custom macroables inside methods is that the method itself doesn’t take the parameters instead the returning callback function passing in the parameters.

Let’s create another simple Macro isGreaterThan

public function isGreaterThan(  ) {
   return function($str,$length){
      return static::length($str) > $length;
   };
}

Now you may use these macros anywhere inside of your Laravel project.

Str::isGreaterThan('thewebtier','10');
Str::appendsTo('usamamuneer','@');

Other Macroable Components in Laravel

As you already know, Macros are defined in any class which extends the Macroable trait. Some of the most important macroable facades are

  • Request
  • Response
  • Route
  • URL
  • Cache
  • File
  • Lang

Conclusion

Try out creating some macros yourself & let us know in the comment section below if you face any problem. We’ll try our best to help you. Follow us on Twitter.