首页 文章

laravel中的抽象Model类如何处理静态动态方法调用,例如“:: find()”,“:: where()”等

提问于
浏览
5

我正在学习如何在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 with message'调用未定义的方法Illuminate \ Database \ Query \ Builder :: fisd()'” .

请问“Builder”这个课如何进入现场?

为什么异常不是“”BadMethodCallException,带有消息'调用未定义的方法Illuminate \ Database \ Eloquent \ Model :: fisd()'“”?

我看不到扩展Builder类的模型类 .

1 回答

  • 6

    发生这种情况的原因是因为它然后在类上触发 __call 方法,该方法将尝试使用 newQuery() 调用该方法,该方法返回 Builder 的实例 .

    当您尝试在类上调用不可访问(或不存在)的方法时,会调用 __call ,如 __callStatic .

    因此,当您尝试静态调用 find() 时,它将被 __callStatic 捕获,因为它不存在,然后又尝试在新实例上调用 find() 再次不存在因此它被 __call 捕获并且它最终尝试调用 Builder 上的那个方法 .

    希望这可以帮助!

相关问题