Laravel 5 Macros: Call and Callstatic

April 21, 2018 —John Koster

The Macroable trait implements PHP's magic __call method to intercept calls to methods when in object context that do not exist in the current class. If a macro with the given method name is found, it is evaluated and the result returned. If no macro is found with the given name, an instance of BadMethodCallException is thrown.

#Signature

The signature of the __call method is:

1public function __call(
2 $method,
3 $parameters
4);

#Macroable Implementation of PHP's Magic __callStatic Method

The Macroable trait implements PHP's magic __callStatic method to intercept calls to a methods when in static context that do not exist on the target class. If a macro with the given method name is found, it is evaluated and the result returned. If no macro is found with the given name, an instance of BadMethodCallException is thrown.

#Signature

The signature of the __callStatic method is:

1public static function __callStatic(
2 $method,
3 $parameters
4);

#Important Notes On __call and __callStatic

Because Macroable depends on both the __call and __callStatic methods to be available for its own use, it is currently not possible to use the Macroable trait in a class that also requires returning a value from either __call or __callStatic without modifying the parent class's __call or __callStatic methods to accommodate the macro features. However, accommodating the macro features in a class that requires one, or both of the above magic methods is quite simple:

1use Illuminate\Support\Macroable;
2 
3class ExampleClass
4{
5 use Macroable {
6 // Because this class also defines a '__call' method, a new
7 // name has to be given to the traits '__call' method. The
8 // new name in this case is 'macroCall'.
9 __call as macroCall;
10 }
11 
12 public function __call($method, $parameters)
13 {
14 // This will first check if a macro exists, and if it does
15 // the '__call' function will return the value of the
16 // 'macroCall' function (which is defined in the 'Macroable')
17 // trait.
18 if (static::hasMacro($method))
19 {
20 return $this->macroCall($method, $parameters);
21 }
22 
23 // If no macro exists, continue with class-specific
24 // implementation of '__call'.
25 }
26 
27}

The above example is actually utilized within the framework itself with the implementation of "\Illuminate\Cache\Repository".

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.