我正在学习如何在laravel中实现某些功能,因为我想了解一些软件设计技巧和原理。
我理解当静态方法调用时,例如" App \ User :: find(1)或App \ User :: whereId(1)"是在一个雄辩的模型上制作的,抽象模型类实现了一种魔术方法" __ callStatic"像这样:
/**
* Handle dynamic static method calls into the method.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public static function __callStatic($method, $parameters)
{
$instance = new static;
return call_user_func_array([$instance, $method], $parameters);
}
我也明白这一行' $ instance = new static;'制作静态调用的任何雄辩模型的实例,例如App \ User。
但是,我完全不了解下一行中的内容" call_user_func_array([$ instance,$ method],$ parameters);"。
从我到目前为止学到的函数call_user_func_array()假设在eloquent模型实例(例如App \ user)上调用$方法(例如find($ parameters))。
但我不明白为什么不是这样,我发现这种方法在雄辩的模型中不存在。我试过调用一个不存在的方法,如" blah()" :
App\User::blah();
但我得到异常" BadMethodCallException,带有消息'调用未定义的方法Illuminate \ Database \ Query \ Builder :: fisd()'"。
请问班级" Builder"进入现场?
为什么异常不是"" BadMethodCallException with message'调用未定义的方法Illuminate \ Database \ Eloquent \ Model :: fisd()'"&#34 ; ?
我看不到扩展Builder类的模型类。
答案 0 :(得分:7)
发生这种情况的原因是因为它会在类上触发__call
方法,该方法将尝试使用newQuery()
调用该方法,该方法返回Builder
的实例。
__call
,如__callStatic
。
因此,当您尝试静态调用find()
时,它会被__callStatic
捕获,因为它不存在,然后又尝试在新实例上调用find()
不存在,所以它被__call
捕获,并最终尝试在Builder
上调用该方法。
希望这有帮助!