Laravel 里为什么可以用Model::where(),却不能用Model::getTable()

发布于 2022-09-06 04:49:29 字数 1046 浏览 32 评论 0

我理解是:

调用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

吾家有女初长成 2022-09-13 04:49:29

在Model中,where方法是不存在的,而getTable方法却是存在的。之所以这么说,是php因为兼容性的考虑,在检查方法是否存在的时候,并不会去检查是不是静态方法,只要方法存在,不管是静态还是非静态,都认为是方法存在的,因此就不会调用__callStatic方法了。

这也就造成了调用Model::where的时候,由于where方法是在Illuminate\Database\Eloquent\Builder中定义的,__call将该方法的调用代理到了Builder上,因此可以调用。而getTable方法,则因为是Model中的实例方法,做方法存在性判断的时候发现方法有了,就不会去调用__callStatic,直接对该方法进行静态调用,所有就抛出了

Non-static method IlluminateDatabaseEloquentModel::getTable() should not be called statically, assuming $this from incompatible context

时光是把杀猪刀 2022-09-13 04:49:29

因为我们定义的 Model 直接继承于 Eloquent/Model

鸟哥在博客中这样说

因为你在一个有 calling scope 的上下文中采用”静态的形式”调用了一个类的非静态方法所致.

我的理解是你在一个定义了 __callStatic 的类中(如 User)调用非静态方法 User::getTable

where 等方法是在 Builder 类中的,Eloquent/Model 不直接继承 Builder

今天小雨转甜 2022-09-13 04:49:29

getTable方法在Model里面定义的是非静态方法

public function getTable()

直接调用PHP就会跳出了一个Strict错误。

而调用Model::where的时候,由于where没有在Model里面定义,PHP会找Model里面的__callStatic,将where方法代理到目标类里面。

Model的__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);
}
七七 2022-09-13 04:49:29

因为getTable 不是静态的方法
public function getTable()
所以报

Non-static method Illuminate\Database\Eloquent\Model::getTable() should not be called statically, assuming $this from incompatible context

又因为,php 在检查类的方法存不存在时不会考虑是否静态类.所以又不会进__callStatic.

又看了一下,你的问题是为什么可以用 model::where ? 可以用modle::where的原因是 model类里没有一个 where的方法所以进了 __callStatic. 请用getTablemodle里有这个类。所以进不了__callStatic.

回头去看了一下鸟个说的那个文章, 下面是文章的例子。https://segmentfault.com/q/10...

<?php

class A
{
    public function __call($name, $args)
    {
        echo "NO\n";
    }

    public static function __callStatic($name, $args)
    {
        echo "YES\n";
    }
}

class B extends A
{
    public function test()
    {
        A::test();
    }

    public static function stest()
    {
        A::test();
    }
}

A::test();

$b = new B();
$b->test();

B::stest();

他有三个输出

A::test();

$b = new B();
$b->test();

B::stest();

需要看清楚的是第一个用的是 A::test() .

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文