Laravel 5 Macros: Creating Callback Macros

April 21, 2018 —John Koster

The first method of creating macros we will explore is the callback function macro. These macros are added to the various classes directly by calling the macro method on the macroable class and then supplying the callback function that will be executed when the macro function is invoked. To create a callback function macro, first locate the desired class to create a macro for. In the following examples, a rot13 macro will be created for the \Illuminate\Support\Str class. The first helper function will be a wrapper of PHP's str_rot13 function, which performs the ROT13 encoding on a given string.

The macro function is easily created like so:

1use \Illuminate\Support\Str;
2 
3Str::macro('rot13', function($value)
4{
5 return str_rot13($value);
6});

After the rot13 macro has been defined, code can be written like the following:

1$value = Str::rot13('test');

In the above example, $value would be assigned the value grfg.

The Macroable traits internal mechanisms allow macros to be called from both static and instance contexts.

Macros essentially become part of the class they are created for because of the internal mechanisms that power them. Because of this, macro functions have access to all the private and protected members of the class they are created for. With this knowledge, very powerful macro functions can be created to add functionality to the framework that would otherwise be difficult to accomplish.

The following code example highlights this fact by returning the $studlyCache member of the \Illuminate\Support\Str class, which is declared to be protected static:

1Str::macro('getStudlyCache', function()
2{
3 return self::$studlyCache;
4});
5 
6// Call the 'studly' function a few times to make sure there
7// are cache entries.
8Str::studly('This is a test');
9Str::studly('This is another test');
10 
11$cacheEntries = Str::getStudlyCache();

After the above code executes, the $cacheEntries variable would have the value:

1array [
2 "This is a test" => "ThisIsATest"
3 "This is another test" => "ThisIsAnotherTest"
4]

Trying to access the $studlyCache member directly would throw an instance of Symfony\Component\Debug \Exception\FatalErrorExcepption with the following message:

1Cannot access protected property
2 Illuminate\Support\Str::$studlyCache

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.