Magic method __call và __callStatic áp dụng cho Laravel

Hai phương thức __call__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