What are magic methods? How to apply in Laravel? The following article will introduce the application of PHP magic method in Laravel, I hope it will be helpful to you!
Laravel takes PHP to a whole new level, providing a great development experience (DX) for your next project. Therefore, some people call it “magic”.
Today, I’m going to show you a Laravel trick,magic method。
What are magic methods?
It is important to understand that magic methods are not exclusive to Laravel, but can be used in any PHP application. Laravel just happens to have some of the most interesting use cases for magic methods.
Magic methods are methods available in any class declared in PHP that provide a way to implement additional functionality in the class.
Here’s a good definition:
The magic method is never called by the programmer – in fact, PHP will call the method behind the scenes. This is why they are called “magic” methods – because they are never called directly, they allow the programmer to do some very powerful things.
There are 15 magic methods in total:
class MyClass
{
public function __construct() {}
public function __destruct() {}
public function __call() {}
public function __callStatic() {}
public function __get() {}
public function __set() {}
public function __isset() {}
public function __unset() {}
public function __sleep() {}
public function __wakeup() {}
public function __toString() {}
public function __invoke() {}
public function __set_state() {}
public function __clone() {}
public function __debuginfo() {}
}Copy after login
If you’ve done some object-oriented programming with PHP, you know__construct
method, which is a magic method. So you’ve been using magic methods.
You also noticed that all magic methods are prefixed with “__”.
Today, we won’t delve into these methods, but only the interesting ones used throughout the Laravel codebase. If anyone else is interested, feel free to check out the documentation below?
PHP: Méthodes magiques – Manual
How Laravel uses magic methods
__get()
Models in Laravel are very special. They do not store property data as direct properties of the class, but inprotected $attributes
property, which is an associative array of all the data held by the model.
Let’s see the difference between simple PHP classes and Laravel model access properties.
<?php
/**
* A normal user class in PHP (not Laravel) will just be a class with the above attributes
*/
class NormalUser
{
public $firstName = 'Alice';
}
$normalUser = new NormalUser;
$normalUser->firstName; // will return 'Alice' after login copy<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* A user class in Laravel
*/
class LaravelUser extends Model
{
/**
* Note that we store all property data in a separate array
*/
protected $attributes = [
'firstName' => 'Alice',
];
}
$laravelUser = new LaravelUser;
$laravelUser->firstName; // still returns 'Alice' after login and copy
We can see that the PHP and Laravel classes above behave exactly the same.
However, in the case of Laravel, properties are not stored like normal PHP, but are centralized in a file called$attributes
in the properties. We still managed to access the correct data, but how?
All this is possible because_get
magic method. Let’s try to implement a simple example ourselves.
<?php
class NormalUser
{
/**
* Declare properties like in Laravel
*/
protected $attributes = [
'firstName' => 'Alice',
];
/**
* __get function receives a parameter
* it will be the name of the property you want to access
* In this example $key = "firstName"
*/
public function __get(string $key)
{
return $this->attributes[$key];
}
}
$normalUser = new NormalUser;
$normalUser->firstName; // will return 'Alice' after login copy
We did it! ?
We need to note that the magic method will only be called if no property with a matching name is found in the class_get
. This is a fallback method, called when PHP cannot find the property being accessed in the class. So in the example below, the magic method is not called at all_get
。
<?php
class NormalUser
{
public $firstName = 'Bob';
protected $attributes = [
'firstName' => 'Alice',
];
public function __get($key)
{
return $this->attributes[$key];
}
}
$normalUser = new NormalUser;
/**
* Since the property exists in the class, Bob will be returned
* So the magic method __get is not called in this example
*/
$normalUser->firstName; copy after login
There’s more going on behind the scenes. If you want to know more about exactly how Laravel’s models are used__get
Yes, you can view the source code below.
laravel/framework
__set()
Use a magic method when trying to set a property not declared in the class_set
. Let’s look again at the difference between normal PHP classes and models in Laravel.
<?php
class NormalUser
{
public $firstName = 'Alice';
}
$normalUser = new NormalUser;
$normalUser->firstName = 'Bob';
$normalUser->firstName; // Will return 'Bob' to log in and copy<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class LaravelUser extends Model
{
protected $attributes = [
'firstName' => 'Alice',
];
}
$laravelUser = new LaravelUser;
$laravelUser->firstName = 'Bob';
$laravelUser->firstName; // Will return 'Bob' as well copy after login
As we can see, in this example we are still trying to influenceBob
value that doesn’t actually exist in the class but is in the attribute$ attributes
middle. Let’s try using the magic method__ set
<?php
class NormalUser
{
public $attributes = [
'firstName' => 'Alice',
];
/**
* The magic method __set receives the $name you want to affect the value on
* and the value
*/
public function __set($key, $value)
{
$this->attributes[$key] = $value;
}
}
$normalUser = new NormalUser;
$normalUser->firstName = 'Bob';
/**
* As we don't have the __get magic method define in this example for simplicity sake,
* we will access the $attributes directly
*/
$normalUser->attributes['firstName']; // Will return 'Bob' to log in and copy
Now let’s get started! We successfully implemented in Laravel__ get
and__ set
Basic usage of magic method! They can be done with just a few lines of code!
Keep in mind that these magic methods are as simple as possible without going into too much detail, because there’s more to that than just use cases, and if you’re curious about how it works, I invite you to do some exploring yourself! (Also feel free to reach out to me on Twitter if you have any questions)
Again, here is a link to the source code if you want to dig further
laravel/framework
Let’s move on to the last and most interesting one! ?
__call()
& __callStatic()
When calling a method not found in the class,__call()
will be called. In laravel, the magic method method makes macros possible in php.
I won’t go into all the details of macros, but if you’re interested, here’s a good article explaining how to use them in a Laravel application?
The Magic of Laravel Macros
Let’s try to see how to write a simple macro example.
<?php
class NormalUser
{
public $firstName = 'Alice';
public $lastName = 'Bob';
}
$normalUser = new NormalUser;
$normalUser->fullName(); // Since the "fullName" method is not declared, this will throw an error after logging in
use__call
, you can define an array containing closure functions, which can be programmatically added to the application during our development.
<?php
class NormalUser
{
public $firstName = 'Alice';
public $lastName = 'Bob';
/**
* Initialize our macro to an empty array to be assigned later
*/
public static $macros = [];
/**
* Define a method to add a new macro
* The first argument is the name of the macro we want to define
* The second parameter is the closure function that will be executed when the macro is called
*/
public static function addMacro($name, $macro) {
static::$macros[$name] = $macro;
}
/**
* "__call" accepts two parameters,
* $name is the name of the function being called, such as "fullName"
* $arguments are all parameters passed to the function, here we use an empty array, because our function does not need to pass parameters
*/
public function __call(string $name, array $arguments) {
/**
* Get the macro by name
*/
$macro = static::$macros[$name];
/**
* Then execute the macro with the parameters
* Remarks: Before calling, we need to bind the closure to "$this", so that the macro method is executed in the same context
*/
return call_user_func_array($macro->bindTo($this, static::class), $arguments);
}
}
$normalUser = new NormalUser;
$normalUser->fullName(); // Breaks here because we neither define a "fullName" macro nor a "fullName" method exists.
/**
* Add "fullName" macro method
*/
NormalUser::addMacro('fullName', function () {
return $this->firstName.' '.$this->lastName;
});
$normalUser->fullName(); // now, returns "Alice Bob" after login copy
Macros are a bit more complicated than that, but we managed to use__call
Magic method to create a simple working version of a macro.
Except for static methods,__callStatic
and__call
are exactly the same.
If you’re going to dig into it yourself, here’s the source code for the macro’s features.
laravel/framework
Summarize
So coders, you’re right that Laravel feels magical when you first use it, but by digging into the source code, you’ll understand how the magic works behind the scenes.
Just like magic in real life, things that don’t make sense don’t happen, and even more so in code. There is always a line of code executing behind the program, but you need to discover it.
English original address: https://dev.to/stvnyung/laravel-greatest-trick-revealed-magic-methods-31om
Translation address: https://learnku.com/laravel/t/40926
The above is what is the magic method? For details on how to use it in Laravel, please pay attention to other related articles on bestcodepaper!
FAQs
What is a magic method in laravel? ›
Magic methods are marked by their double underscore preceding the function name. These pseudo functions define several, very common events in php objects including getters and setters. Laravel makes great use of magic functions to allow for and enhance dynamic objects and methods.
What is magic method? ›Magic methods are special methods in python that have double underscores (dunder) on both sides of the method name. Magic methods are predominantly used for operator overloading.
What are magic methods and use in PHP? ›Magic methods are special methods which override PHP's default's action when certain actions are performed on an object. All methods names starting with __ are reserved by PHP. Therefore, it is not recommended to use such method names unless overriding PHP's behavior.
What is magic method in PHP 8? ›There are several magic methods in PHP. __constuct() magic method is called when a new class object is instantiated with new Foo() pattern, the __get() magic method is called when non-existing class property is requested, __toString() magic method is called when a class object is coerced to a string , and so on.