Hello friends! As you know, Laravel
is a new framework but has completely outperformed other senior PHP frameworks in terms of popularity. So have you ever asked WHAT, what makes Laravel so prominent?
In this article, I want to introduce to you the characteristics of PHP that play an important role in building such a great Laravel framework, not to mention PHP’s Magic Methods
.
So what is it ‘magic’ like that, let’s find out in this article!
What are Magic Methods?
First of all, you must understand that magic methods
not exclusive to Laravel, but are available in any PHP application. Because I am working with Laravel Framework, so I would like to allow this article to give examples related to this framework.
Magic methods are special methods for customizing events in PHP. Simply put, it provides an additional way to solve a problem. Magic methods are used to handle objects in OOPS.
Magic methods will never be called directly, you can call magic methods behind the scenes
.
There are currently 15 magic methods
:
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 31 32 33 | <span class="token keyword">class</span> <span class="token class-name">MyClass</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__construct</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__destruct</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__call</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__callStatic</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__set</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__isset</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__unset</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__sleep</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__wakeup</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__toString</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__invoke</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__set_state</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__clone</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__debuginfo</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
If you have been working with OOPs PHP
in general, Laravel in particular, you have come across the __construct()
method somewhere. The __contruct
function will automatically be called when we instantiate an object (also called the constructor). So you’ve used the method magics
, right?
You will also notice that all magic methods
have a prefix __
.
This article, I can not introduce all the magic method
, I just mentioned 4 functions: __get()
, __set()
, __call()
, __callStatic()
used in Laravel codebase. If you are interested in other functions, you can find out more here .
How has Laravel used ‘magic’?
__get ()
In Laravel’s Model
is really special. They do not store attribute data as a Class attribute directly, but one of them has a protected $attributes
, which is an array that stores the Model’s attribute attributes.
Differences between usage between the class in plain PHP and the Model class in Laravel
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token comment">/** * A user class in PHP (without Laravel) will be just a class with the said attributes */</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token variable">$firstName</span> <span class="token operator">=</span> <span class="token single-quoted-string string">'Quan'</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span> <span class="token punctuation">;</span> <span class="token keyword">echo</span> <span class="token variable">$user</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">firstName</span> <span class="token punctuation">;</span> <span class="token comment">// Will return 'Quan'</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <span class="token keyword">namespace</span> <span class="token package">App</span> <span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Illuminate Database Eloquent Model</span> <span class="token punctuation">;</span> <span class="token comment">/** * A user class in Laravel */</span> <span class="token keyword">class</span> <span class="token class-name">LaravelUser</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span> <span class="token punctuation">{</span> <span class="token comment">/** * Note that store all the attributes data in one and single array */</span> <span class="token keyword">protected</span> <span class="token variable">$attributes</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'firstName'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token single-quoted-string string">'Quan'</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token variable">$laravelUser</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">LaravelUser</span> <span class="token punctuation">;</span> <span class="token keyword">echo</span> <span class="token variable">$laravelUser</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">firstName</span> <span class="token punctuation">;</span> <span class="token comment">// Will return 'Quan' as well</span> |
We can see that two working examples produce identical results. However, in Laravel attribute attribute
not stored as in PHP, instead all attribute attribute
are defined in an attribute named $attributes
. So why when accessing the needed properties, they can return the right data: -? : -? : -?
Simply because behind the road there is always a __get
magic method
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token comment">/** * Declare the attributes that same way as in Laravel */</span> <span class="token keyword">protected</span> <span class="token variable">$attributes</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'firstName'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token single-quoted-string string">'Quan'</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token comment">/** * The function __get receive one parameter * which will be the name of the attribute you want to access * in this case $key = "firstName" */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__get</span> <span class="token punctuation">(</span> <span class="token variable">$key</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">attributes</span> <span class="token punctuation">[</span> <span class="token variable">$key</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span> <span class="token punctuation">;</span> <span class="token keyword">echo</span> <span class="token variable">$user</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">firstName</span> <span class="token punctuation">;</span> <span class="token comment">// Will return 'Quan'</span> |
Everything looks good!
We should note that the __get()
magic method is only called when we access non-existent or protected
( private
or private
) properties in the Class. To clarify this, let’s look at the example below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token variable">$firstName</span> <span class="token operator">=</span> <span class="token single-quoted-string string">'Quan'</span> <span class="token punctuation">;</span> <span class="token keyword">protected</span> <span class="token variable">$attributes</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'firstName'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token single-quoted-string string">'Vinh'</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__get</span> <span class="token punctuation">(</span> <span class="token variable">$key</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">attributes</span> <span class="token punctuation">[</span> <span class="token variable">$key</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span> <span class="token punctuation">;</span> <span class="token comment">/** * Will return 'Quan' as the attribute exists in the class * so the magic method __get doesn't get call in this case */</span> <span class="token keyword">echo</span> <span class="token variable">$user</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">firstName</span> <span class="token punctuation">;</span> |
There are many more things that Laravel does when the __get()
magic methods are called, details can be found here .
__set ()
The __set()
method is called when we pass data to a nonexistent property or property ( protected
or private
) in the Class.
Let’s read on for an example to see the difference between the usage between the pure PHP class and the Laravel Model class!
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token variable">$firstName</span> <span class="token operator">=</span> <span class="token single-quoted-string string">''</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span> <span class="token punctuation">;</span> <span class="token variable">$user</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">firstName</span> <span class="token operator">=</span> <span class="token single-quoted-string string">'Quan'</span> <span class="token punctuation">;</span> <span class="token keyword">echo</span> <span class="token variable">$user</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">firstName</span> <span class="token punctuation">;</span> <span class="token comment">// Will return 'Quan'</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <span class="token keyword">namespace</span> <span class="token package">App</span> <span class="token punctuation">;</span> <span class="token keyword">use</span> <span class="token package">Illuminate Database Eloquent Model</span> <span class="token punctuation">;</span> <span class="token keyword">class</span> <span class="token class-name">LaravelUser</span> <span class="token keyword">extends</span> <span class="token class-name">Model</span> <span class="token punctuation">{</span> <span class="token keyword">protected</span> <span class="token variable">$attributes</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'firstName'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token single-quoted-string string">''</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token variable">$laravelUser</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">LaravelUser</span> <span class="token punctuation">;</span> <span class="token variable">$laravelUser</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">firstName</span> <span class="token operator">=</span> <span class="token single-quoted-string string">'Quan'</span> <span class="token punctuation">;</span> <span class="token keyword">echo</span> <span class="token variable">$laravelUser</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">firstName</span> <span class="token punctuation">;</span> <span class="token comment">// Will return 'Quan' as well</span> |
In the example, we are trying to assign the value
‘Quan’ to the attribute attribute firstName
does not exist in the Class that is defined in the $attributes
.
You see the title is __set()
, many of you probably guessed that the magic of the __set()
function to handle it, but let’s try it out: -? : -? : -?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token variable">$attributes</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'firstName'</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token single-quoted-string string">''</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token comment">/** * The magic method __set receives the $name you want to affect the value on * and the value */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__set</span> <span class="token punctuation">(</span> <span class="token variable">$key</span> <span class="token punctuation">,</span> <span class="token variable">$value</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">attributes</span> <span class="token punctuation">[</span> <span class="token variable">$key</span> <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$value</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span> <span class="token punctuation">;</span> <span class="token variable">$user</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">firstName</span> <span class="token operator">=</span> <span class="token single-quoted-string string">'Quan'</span> <span class="token punctuation">;</span> <span class="token keyword">echo</span> <span class="token variable">$user</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">attributes</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'firstName'</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token comment">// Will return 'Quan'</span> <span class="token comment">// echo $user->firstName;</span> |
That’s it, we have successfully implemented the basic use of the __get()
and __set()
magic methods in Laravel. I am trying to get a simple example so you can have a simple understanding of the Laravel works, details about __set()
can be found here .
__call () & __callStatic ()
The __call()
method is called when we call methods that are not accessible within the scope of an object. In Laravel, this magic method is used to create macro
contained in PHP.
What is the task of macros? The nature of macros differs in different languages, but it all carries a common mission of performing a task we already have.
Now let’s see how we can create macro
in plain PHP …
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token variable">$firstName</span> <span class="token operator">=</span> <span class="token single-quoted-string string">'Quan'</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token variable">$lastName</span> <span class="token operator">=</span> <span class="token single-quoted-string string">'Tien'</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span> <span class="token punctuation">;</span> <span class="token variable">$user</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">fullName</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
This program will run without error because the fullName
method fullName
not been declared in the User
class. We get the message Call to undefined method User :: fullName ()
Now with the __call
magic method, we can define an array that will contain the Closure function.
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token variable">$firstName</span> <span class="token operator">=</span> <span class="token single-quoted-string string">'Quan'</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token variable">$lastName</span> <span class="token operator">=</span> <span class="token single-quoted-string string">'Tien'</span> <span class="token punctuation">;</span> <span class="token comment">/** * We initialise our macros as an empty array that we will fill */</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token variable">$macros</span> <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token comment">/** * We define this method to add new macro as we go * the first argument will be the name of the macro we want to define * the second will be a Closure function that will be executed when calling the macro */</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">function</span> <span class="token function">addMacro</span> <span class="token punctuation">(</span> <span class="token variable">$name</span> <span class="token punctuation">,</span> <span class="token variable">$macro</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">static</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token variable">$macros</span> <span class="token punctuation">[</span> <span class="token variable">$name</span> <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$macro</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">/** * "__call" receives two parameters, * $name which will be the name of the function called in our case 'fullName' * $arguments which will be all the arguments passed in the function in our case it'll just be an empty array as we can't pass any arguments in our function */</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__call</span> <span class="token punctuation">(</span> string <span class="token variable">$name</span> <span class="token punctuation">,</span> <span class="token keyword">array</span> <span class="token variable">$arguments</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">/** * We retrieve the macro with the right name */</span> <span class="token variable">$macro</span> <span class="token operator">=</span> <span class="token keyword">static</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token variable">$macros</span> <span class="token punctuation">[</span> <span class="token variable">$name</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token comment">/** * Then we execute the macro with the arguments * Note: we need to bind the Closure with "$this" before calling it to allow the macro method to act in the same context */</span> <span class="token keyword">return</span> <span class="token function">call_user_func_array</span> <span class="token punctuation">(</span> <span class="token variable">$macro</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">bindTo</span> <span class="token punctuation">(</span> <span class="token variable">$this</span> <span class="token punctuation">,</span> <span class="token keyword">static</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token variable">$arguments</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token variable">$user</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">User</span> <span class="token punctuation">;</span> <span class="token variable">$user</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">fullName</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// This will still break as we didn't define the macro 'fullName' yet and the method 'fullName' doesn't exist either</span> <span class="token comment">/** * Add the macro function 'fullName' */</span> User <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">addMacro</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'fullName'</span> <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">firstName</span> <span class="token punctuation">.</span> <span class="token single-quoted-string string">' '</span> <span class="token punctuation">.</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">lastName</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$user</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">fullName</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Now, returns 'Quan Tien'</span> |
So we know how to create macro
using the __call
magic method.
With the __callStatic
magic method, it works similarly to the _call
magic method, but for phương thức tĩnh static
.
You can refer to Macroable
in Laravel [here]. ( Https://github.com/laravel/framework/blob/7.x/src/Illuminate/Support/Traits/Macroable.php )
Conclude
Above I have shown you how Laravel uses magic methods
in their basecode. This article may seem a bit deep about the framework for those who are new to Laravel, but in general, if you are sure of PHP knowledge, it is not difficult at all. Hopefully through this article, you can understand more lines of code I wrote it is handled like.
Thank you for reading my article !!!
References
https://www.php.net/manual/en/language.oop5.magic.php
https://github.com/laravel/framework/blob/7.x/src/Illuminate/Database/Eloquent/Model.php
https://github.com/laravel/framework/blob/7.x/src/Illuminate/Support/Traits/Macroable.php