误解一般解释__call方法在对象方法不存在时调用__callStatic方法在调用对象静态方法不存在时调用如classCar{publicfunction__call($method),$params=[]){echo"汽车呼叫\n";}}(newCar())->color();classBus{publicstaticfunction__callStatic($method,$params=[]){echo"BuscallStatic\n";}}巴士::isSale();特例其实上面的解释在某些情况下是正确的。但是在一些特殊的情况下,如果你按照这个解释去理解,你会发现这个结果不可思议。下面举几个例子来说明。__call的调用重点看方法是否可以访问classCar{publicfunction__call($method,$params=[]){echo"carcall\n";}publicfunctioncolor(){echo"colorred\n";}protectedfunctionisRed(){echo"yesisRed\n";}公共函数checkColor(){$this->color();$this->isRed();}}$car=newCar();$car->color();$car->isRed();$car->checkColor();输出结果为colorredcarcallisRedcolorredyesisRed从上面可以看出是否调用__call取决于当前调用者是否可以访问要调用的函数,如果可以,直接调用该函数,如果不能,则调用魔术方法__call。因此,是否调用与可达性有关。__callStatic关注的是方法是否可以静态访问。下面再看一个静态调用的例子classCar{publicstaticfunction__callStatic($method,$params=[]){echo"carcallStatic\n";}publicfunctioncolor(){echo"colorred\n";}protectedfunctionisRed(){echo"yesisRed\n";}publicfunctioncheckColor(){Car::color();汽车::是红色的();}Car::color();Car::isRed();(newCar())->checkColor();输出colorredcarcallStaticisRedcolorredyesisRed,外部静态调用Car::color,有Notice级错误提示,但没有内部呼叫。因此,__callStatic关注的是函数是否可以在调用位置静态访问。如果可以访问,直接执行该方法。如果不是,则执行__callStatic方法。__call和__callStatic同时存在。当方法不可访问时,__call和__callStatic方法的具体调用不是根据调用方法是否为静态调用,而是根据上下文。如果上下文在可以访问调用对象的对象中,则调用__call。在静态上下文中调用不可访问的方法时,调用__callStaticclassCar{publicstaticfunction__callStatic($method,$params=[]){echo"carcallStatic$method\n";}publicfunction__call($method,$params=[]){echo"carcall$method\n";}publicfunctioncheckColor(){Car::color();汽车::是红色的();}}$car=newCar();Car::color();Car::isRed();$car->color();$car->isRed();(newCar())->checkColor();输出是carcallStaticcolorcarcallStaticisRedcarcallcolorcarcallisRedcarcallcolorcarcallisRed从结果可以看出,外部静态调用color,isRed方法,上下文是静态的,所以实现是__callStatic。在checkColor方法中,调用的上下文是在当前类对象Car中,即使静态调用了color和isRed,最终还是执行了_??_call方法。总结1)__call方法关注的是方法是否可以被访问,而不仅仅是是否存在。2)__callStatic方法关注的是方法是否可以静态访问,而不是方法是否存在或者是静态方法。3)__call、__callStatic的具体执行是根据调用的上下文来的。如果在静态上下文中,则调用__callStatic。如果在对象的在线文本中,则调用__call
