Рубрики
Uncategorized

Новое понимание магических методов

Автор оригинала: David Wong.

Общее объяснение недопонимания

__call Метод вызывается, когда метод объекта не существует

____call Статический Метод вызывается, когда статический метод вызывающего объекта не существует

например

class Car{
    public function __call($method,$params=[]){
        echo "car call\n";
    }
}

(new Car())->color();

class Bus{
    public static function __callStatic($method,$params=[]){
        echo "Bus callStatic\n";
    }
}

Bus::isSale();

Исключительный случай

На самом деле, приведенное выше объяснение в некоторых случаях верно. Но в некоторых особых случаях, если вы последуете этому объяснению, вы обнаружите, что результат непостижим.

Вот несколько примеров.

__Call вызовы фокусируются на том, можно ли получить доступ к методу

class Car{
    public function __call($method,$params=[]){
        echo "car call\n";
    }

    public function color(){
        echo "color red\n";
    }

    protected function isRed(){
        echo "yes is Red\n";
    }

    public function checkColor(){
        $this->color();
        $this->isRed();
    }
}
$car = new Car();
$car->color();
$car->isRed();

$car->checkColor();

На выходе получается

color red
car call isRed
color red
yes is Red

Как видно из вышесказанного, стоит ли звонить __звонить Это зависит от того, может ли текущий вызывающий абонент получить доступ к вызываемой функции. Если к нему можно получить доступ, он вызовет функцию напрямую. Если к нему невозможно получить доступ, он вызовет волшебный метод. __вызов 。 Следовательно, вызов касается доступности.

__Callstatic фокусируется на том, можно ли получить доступ к методу статически

Далее давайте рассмотрим другой пример статического вызова

class Car{
    public static function __callStatic($method,$params=[]){
        echo "car callStatic\n";
    }

    public function color(){
        echo "color red\n";
    }

    protected function isRed(){
        echo "yes is Red\n";
    }

    public function checkColor(){
        Car::color();
        Car::isRed();
    }
}

Car::color();
Car::isRed();
(new Car())->checkColor();

На выходе получается

color red
car callStatic isRed
color red
yes is Red

И вызывается статически снаружи Автомобиль::цвет С Уведомлением Подсказкой об ошибке уровня, но внутренние вызовы этого не делают.

Итак, __callStatic Проблема заключается в том, можно ли получить доступ к функции статически в месте вызова. При наличии доступа метод выполняется напрямую. Если нет, выполните __вызов статического Метода

__ Случай одновременного вызова и ﹣ callstatic

Когда метод недоступен, вызов вызова статического метода основан не на том, является ли метод вызова статическим или нет, а на контексте. Если контекст находится в объекте, имеющем доступ к вызывающему объекту, то __вызов Вызывает метод доступа в статическом контексте, вызов __callStatic

class Car{
    public static function __callStatic($method,$params=[]){
        echo "car callStatic $method\n";
    }

    public  function __call($method,$params=[]){
        echo "car call $method\n";
    }

    public function checkColor(){
        Car::color();
        Car::isRed();
    }
}


$car = new Car();
Car::color();
Car::isRed();

$car->color();
$car->isRed();

(new Car())->checkColor();

На выходе получается

car callStatic color
car callStatic isRed
car call color
car call isRed
car call color
car call isRed

Как вы можете видеть из результатов, внешние статические вызовы цвет , Красный Метод, контекст статичен, поэтому выполнение __callStatic

В то время как в методе check Color контекст вызова находится в текущем объекте класса Car Даже при статическом вызове color , isRed , конечным выполнением является __вызов Метода.

резюме

1) __вызов Методы фокусируются на том, можно ли получить доступ к методу, а не только на том, существует ли он

2) __вызов статического Метода фокусируется на том, можно ли получить доступ к методу статически, а не на том, существует ли метод или является статическим методом.

3) Конкретная реализация __вызов , |/__вызов Статический , в зависимости от контекста вызова. Если в статическом контексте __вызов статического . Если он находится в онлайн-тексте объекта, вызовите __вызов

Статья начинается с официального аккаунта [Старого Вана, который написал PHP].