Laravel 里为什么可以用Model::where(),却不能用Model::getTable()
我理解是:
调用 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()
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在Model中,
where
方法是不存在的,而getTable
方法却是存在的。之所以这么说,是php因为兼容性的考虑,在检查方法是否存在的时候,并不会去检查是不是静态方法,只要方法存在,不管是静态还是非静态,都认为是方法存在的,因此就不会调用__callStatic
方法了。这也就造成了调用
Model::where
的时候,由于where
方法是在Illuminate\Database\Eloquent\Builder
中定义的,__call
将该方法的调用代理到了Builder
上,因此可以调用。而getTable
方法,则因为是Model
中的实例方法,做方法存在性判断的时候发现方法有了,就不会去调用__callStatic
,直接对该方法进行静态调用,所有就抛出了因为我们定义的
Model
直接继承于Eloquent/Model
鸟哥在博客中这样说
我的理解是你在一个定义了
__callStatic
的类中(如User
)调用非静态方法User::getTable
。而
where
等方法是在Builder
类中的,Eloquent/Model
不直接继承Builder
。getTable方法在Model里面定义的是非静态方法
直接调用PHP就会跳出了一个Strict错误。
而调用Model::where的时候,由于where没有在Model里面定义,PHP会找Model里面的__callStatic,将where方法代理到目标类里面。
Model的
__callStatic
方法注释也解释的很清楚因为
getTable
不是静态的方法public function getTable()
所以报
又因为,php 在检查类的方法存不存在时不会考虑是否静态类.所以又不会进
__callStatic
.又看了一下,你的问题是为什么可以用
model::where
? 可以用modle::where
的原因是model
类里没有
一个where
的方法所以进了__callStatic
. 请用getTable
时modle
里有这个类。所以进不了__callStatic
.回头去看了一下鸟个说的那个文章, 下面是文章的例子。https://segmentfault.com/q/10...
他有三个输出
需要看清楚的是第一个用的是
A::test()
.