Общее объяснение недопонимания
__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].