Xin chào các bạn! Như các bạn biết thì Laravel
là 1 framework mới nhưng đã vượt trội hoàn toàn so với các Framework đàn anh đàn chị khác của PHP về sự phổ biến. Vậy bạn có bao giờ bạn đặt câu hỏi WHAT, điều gì làm cho Laravel trở nên nổi bật như vậy không?
Trong bài này, mình muốn giới thiệu cho các bạn đặc trưng của PHP đóng góp vai trò quan trọng trong việc xây dựng framework Laravel tuyệt vời như vậy, không thể không nhắc đến Magic Methods
của PHP.
Vậy nó có điều gì ‘ma thuật’ như vậy, hãy cùng mình tìm hiểu trong bài viết này nhé!
Magic Methods là gì?
Điều đầu tiên, các bạn phải hiểu rằng các magic methods
không chỉ dành riêng cho Laravel, mà nó có sẵn trong bất kỳ ứng dụng PHP nào. Vì mình đang làm việc với Framework Laravel nên mình xin phép bài viết này lấy ví dụ liên quan đến framework này ạ.
Magic methods là các phương thức đặc biệt để tùy biến các sự kiện trong PHP. Hiểu đơn giản là nó cung cấp thêm cách giải quyết 1 vấn đề. Magic methods được dùng để xử lý các đối tượng trong OOPS.
Các magic methods sẽ không bao giờ được gọi trực tiếp, có thể gọi magic methods là behind the scenes
.
Hiện tại có tổng 15 hàm 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> |
Nếu bạn, đã từng làm việc với OOPs PHP
nói chung, Laravel nói riêng thì bạn đã bắt gặp ở đâu đó phương thức __construct()
. Hàm __contruct
sẽ tự động được gọi khi ta khởi tạo 1 đối tượng (còn được gọi là hàm khởi tạo). Vậy là bạn đã từng sử dụng method magics
rồi phải không?
Bạn cũng sẽ nhận thấy rằng tất cả các magic methods
đều có tiền tố prefix __
.
Bài viết này, mình không thể giới thiệu hết các magic method
, mình chỉ nêu ra 4 hàm: __get()
, __set()
, __call()
, __callStatic()
được sử dụng trong codebase của Laravel. Nếu bạn quan tâm đến các hàm khác, có thể tìm hiểu thêm tại đây.
Laravel đã sử dụng ‘ma thuật’ như nào?
__get()
Trong Model
của Laravel thực sự đặc biệt. Chúng không lưu trữ dữ liệu thuộc tính dưới dạng thuộc tính trực tiếp của Class nhưng trong đó có 1 thuộc tính protected $attributes
, là mảng lưu các thuộc tính attribute của Model.
Sự khác biệt giữa cách sử dụng giữa lớp trong PHP thuần và lớp Model trong 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">IlluminateDatabaseEloquentModel</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> |
Chúng ta có thể thấy 2 ví dụ hoạt động cho ra kết quả giống hệt nhau. Tuy nhiên, trong Laravel các thuộc tính attribute
không được lưu như trong PHP, thay vào đó, tất cả thuộc tính attribute
được định nghĩa trong 1 thuộc tính có tên $attributes
. Vậy tại sao khi truy cập vào thuộc tính cần, chúng lại có thể trả về đúng dữ liệu được nhỉ 😕 😕 😕
Đơn giản vì phía sau con đường luôn có magic method __get
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> |
Mọi thứ có vẻ ổn!
Chúng ta cần lưu ý rằng magic method __get()
chỉ được gọi khi ta truy cập vào thuộc tính không tồn tại hoặc thuộc tính không thể truy cập (protected
hoặc private
) trong Class. Để làm rõ điều này, hãy cùng xem ví dụ dưới đây:
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> |
Còn nhiều thứ được Laravel thực hiện khi hàm __get()
magic methods được gọi, chi tiết các bạn có thể xem tại đây.
__set()
Magic method __set()
được gọi khi ta truyền dữ liệu vào thuộc tính không tồn tại hoặc thuộc tính (protected
hoặc private
) trong Class.
Cùng mình xem tiếp ví dụ để xem sự khác biệt giữa cách sử dụng giữa lớp trong PHP thuần và lớp Model trong Laravel nhé!
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">IlluminateDatabaseEloquentModel</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> |
Trong ví dụ, ta đang cố gắng gán value
‘Quan’ vào thuộc tính attribute firstName
không tồn tại trong Class mà nó được định nghĩa trong thuộc tính $attributes
.
Các bạn nhìn title là __set()
, chắc nhiều bạn cũng đoán được là dùng ma thuật của hàm __set()
để xử lí chứ gì hãy cùng thử thực hiện xem sao 😕 😕 😕
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> |
Vậy là xong, chúng ta đã thực hiện thành công việc sử dụng cơ bản magic method __get()
và __set()
trong Laravel. Mình đang cố gắng lấy ví dụ đơn giản để bạn có thể hiểu đơn giản về các mà Laravel làm việc, chi tiết về __set()
các bạn có thể xem thêm tại đây.
__call() & __callStatic()
Magic method __call()
được gọi khi ta gọi phương thức không được phép truy cập trong phạm vi của một đối tượng. Trong Laravel, magic method này được sử dụng để tạo ra các macro
có trong PHP.
Nhiệm vụ của macro là gì? Thì nhiệm của macro khác nhau ở các ngôn ngữ khác nhau, tuy nhiên nó đều mang một sứ mệnh chung là thực hiện một nhiệm vụ mầ chúng ta định sẵn.
Bây giờ, thử xem làm thế nào chúng ta có thể tạo macro
trong PHP thuần nhé…
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> |
Đoạn chương trình này khi chạy chắc chắn sẽ gặp lỗi vì phương thức fullName
chưa được khai báo trong class User
. Chúng ta nhận được thông báo Call to undefined method User::fullName()
Bây giờ với magic method __call
, ta có thể định nghĩa 1 mảng sẽ chứa hàm Closure.
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> |
Vậy là chúng ta đã biết tạo macro
bằng việc sử dụng magic method __call
.
Với magic method __callStatic
hoạt động tương tự như magic method _call
nhưng đối với các phương thức tĩnh static
.
Bạn có thể tham khảo Macroable
trong Laravel [tại đây].(https://github.com/laravel/framework/blob/7.x/src/Illuminate/Support/Traits/Macroable.php)
Kết luận
Trên đây mình đã giới thiệu cho các bạn cách Laravel sử dụng magic methods
trong basecode của họ. Bài viết này có vẻ hơi sâu về framework với những bạn mới tìm hiểu về Laravel nhưng chung quy lại thì nếu bạn chắc về kiến thức PHP thì cũng không gặp khó khăn gì cả. Mong qua bài viết này, các bạn có hiểu được thêm dòng code mình viết ra nó được xử lí như nào.
Cảm ơn bạn đã đọc bài viết của mình!!!
Tài liệu tham khảo
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