Hai phương thức __call và __callStatic là các hàm dùng để bắt lỗi khi gọi đến phương thức (function) chưa được định nghĩa trong lớp (class) của đối tượng
1. Phương thức __call
Phương thức __call sẽ được gọi khi bạn gọi đến một phương thức (không phải static) chưa được định nghĩa trong lớp của đối tượng
class Animal
{
}
$animal = new Animal();
$animal->name();
Khi bạn chạy sẽ có thông báo lỗi phương thức chưa được định nghĩa.
class Animal
{
public function __call($name, $arguments)
{
echo 'Phương thức ' . $name . ' chưa được định ngĩa';
}
}
$animal = new Animal();
$animal->name();
Lúc này khi bạn chạy sẽ nhận được kết quả "Phương thức name chưa được định nghĩa.
2. Phương thức __callStatic
Giống với phương thức __call, nhưng chỉ khác là phương thức này dùng cho trường hợp bạn gọi các phương thức static
class Animal
{
public static function __callStatic($name, $arguments)
{
echo 'Phương thức static ' . $name . ' chưa được định nghĩa';
}
}
Animal::eat();
3. Laravel đã áp dụng 2 phương thức này như thế nào
- Lấy một ví dụ về việc dùng Eloquent trong Laravel, bạn có thể dùng
ModelName::where('id', '>', 10)
->where('status', 1)
->get();
Bạn để ý là where vừa được gọi dạng static và không phải static, vì sao lại vậy, không lẽ là nó vừa được khai báo dạng static và dạng không phải static.
Ở đây Laravel đã dùng hàm __callStatic để xử lý trường hợp này
Laravel chỉ khai báo hàm where ở dạng không phải static và dùng hàm __callStatic để khởi tạo đối tượng và lại gọi đến hàm where như ở dưới đây.
public static function __callStatic($method, $parameters)
{
return (new static)->$method(...$parameters);
}
- Một ví dụ nữa việc Laravel dùng hàm __call cho Eloquent
Bạn tìm trong class Model của Laravel vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php không hề được khai báo hàm insert, hay hàm where như ở trên, nhưng khi bạn gọi ModelName::insert(), ModelName::where() thì vẫn chạy bình thường.
Thực tế thì nó đã dùng hàm __call để gọi đến Illuminate\Database\Query\Builder, và hàm insert, where được khai báo ở đây.
public function __call($method, $parameters)
{
if (in_array($method, ['increment', 'decrement'])) {
return $this->$method(...$parameters);
}
try {
return $this->newQuery()->$method(...$parameters);
} catch (BadMethodCallException $e) {
throw new BadMethodCallException(
sprintf('Call to undefined method %s::%s()', get_class($this), $method)
);
}
}
Hi vọng bài viết sẽ giúp bạn hiểu thêm được hai phương thức __call và __callStatic trong PHP và các nó được áp dụng trong Laravel.
Bài viết từ pinlaz.com