我理解是:
调用 Model::where()
,Model
里没有静态方法 where()
,于是会触发 __callStatic()
,
在 __callStatic()
中会试图去调用实例方法 where()
,Model
也没有 where()
,于是触发 __call()
,
在 __call()
中实例化 \Illuminate\Database\Eloquent\Builder
,然后调用 Builder
的实例方法 where()
。
调用 Model::getTable()
Model
里没有静态方法 getTable()
,于是会触发 __callStatic()
,
在 __callStatic()
中会试图去调用实例方法 getTable()
,Model
有定义,所以应该直接调用getTable()
。
但是却报错
Non-static method Illuminate\Database\Eloquent\Model::getTable() should not be called statically, assuming $this from incompatible context
查了一下错误的原因,鸟哥在这篇文章解释了,PHP 的 Calling Scope
问题是,那为什么可以用 Model::where()
?
在Model中,
where
方法是不存在的,而getTable
方法却是存在的。之所以这么说,是php因为兼容性的考虑,在检查方法是否存在的时候,并不会去检查是不是静态方法,只要方法存在,不管是静态还是非静态,都认为是方法存在的,因此就不会调用__callStatic
方法了。这也就造成了调用
Model::where
的时候,由于where
方法是在Illuminate\Database\Eloquent\Builder
中定义的,__call
将该方法的调用代理到了Builder
上,因此可以调用。而getTable
方法,则因为是Model
中的实例方法,做方法存在性判断的时候发现方法有了,就不会去调用__callStatic
,直接对该方法进行静态调用,所有就抛出了