A General Explanation of Misunderstanding
__call
Method is called when the object method does not exist
__callStatic
Method is called when the static method of the calling object does not existfor example
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();
Exceptional case
In fact, the above explanation is correct in some cases. But in some special cases, if you follow this interpretation, you will find the results incredible.
The following are some examples to illustrate.
_ call calls focus on whether methods can be accessed
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();
The output is
color red car call isRed color red yes is Red
As you can see from the above, whether or not to call __call depends on whether the current caller can access the function to be called. If it can be accessed, it will call the function directly. If it can not be accessed, it will call the magic method __call. Therefore, the call concerns accessibility.
_ callStatic focuses on whether methods can be accessed statically.
Next, let's look at another example of static invocation.
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();
Output content
color red car callStatic isRed color red yes is Red
Car::color is called externally in a static manner with a Notice level error prompt, but there is no internal call.
So _callStatic is concerned about whether functions can be accessed statically at the call location. If it can be accessed, the method is executed directly. If not, execute the _callStatic method
_ The coexistence of call and _callStatic
When a method is not accessible, the _call and _callStatic methods are specifically invoked based not on whether the invocation method is static, but on the context in which it is invoked. If the context is in the object that can be accessed by the calling object, call __call and invoke an __callStatic when you call an access method in the static context.
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();
Output content
car callStatic color car callStatic isRed car call color car call isRed car call color car call isRed
As you can see from the result, the external static call color,isRed method, the context is static, so the _callStatic is executed.
In the checkColor method, the context of the call is in the current class object Car, even if it calls color,isRed in a static way, and finally executes the _call method.
summary
1) _call method concerns whether the method can be accessed, not just whether it exists.
2) The _callStatic method focuses on whether the method can be accessed statically, rather than whether the method exists or not.
3) The specific execution of _call, _callStatic is based on the context of the call. Call _callStatic if it is in a static context. If it is in the online text of the object, call \
The article was first published on the public number "Lao Wang of PHP" and reprinted to indicate its origin.