为什么我在Eloquent模型中调用方法时会得到'非静态方法不应该被静态调用'?

Sam*_*son 66 php laravel eloquent

我试图在我的控制器中加载我的模型并尝试这样做:

return Post::getAll();
Run Code Online (Sandbox Code Playgroud)

得到了错误 Non-static method Post::getAll() should not be called statically, assuming $this from incompatible context

模型中的函数如下所示:

public function getAll()
{

    return $posts = $this->all()->take(2)->get();

}
Run Code Online (Sandbox Code Playgroud)

在控制器中加载模型然后返回其内容的正确方法是什么?

Rub*_*zzo 87

您将方法定义为非静态方法,并尝试将其作为静态方式调用.那说......

  1. ...如果要调用静态方法,则应使用::并将方法定义为static.

    // Defining a static method in a Foo class.
    public static function getAll() { /* code */ }
    
    // Invoking that static method
    Foo::getAll();
    
    Run Code Online (Sandbox Code Playgroud)
  2. ...否则,如果你想调用一个实例方法,你应该实例化你的类,使用->.

    // Defining a non-static method in a Foo class.
    public function getAll() { /* code */ }
    
    // Invoking that non-static method.
    $foo = new Foo();
    $foo->getAll();
    
    Run Code Online (Sandbox Code Playgroud)

注意:在Laravel中,几乎所有Eloquent方法都返回模型的实例,允许您链接方法,如下所示:

$foos = Foo::all()->take(10)->get();
Run Code Online (Sandbox Code Playgroud)

在该代码中,我们通过Facade 静态调用该all方法.之后,所有其他方法都被称为实例方法.

  • `在 Laravel 中,几乎所有的 Eloquent 方法都被定义为静态的`......这是一种误解。**NONE** 是静态的。 (9认同)
  • **是的,在Laravel中,没有任何Eloquent方法被定义为静态**,我们可以_use_它们被定义为静态,但这是一个Facade,更多关于此:http://laravel.com/docs/facades (4认同)
  • 尽管响应是真实的,但在 Laravel 的上下文中,这不太可能是该线程上的用户正在寻找的修复。应删除此答案,并将 keithics 答案标记为正确。 (3认同)

kei*_*ics 29

为什么不尝试添加Scope?范围是Eloquent的一个非常好的特征.

class User extends Eloquent {

    public function scopePopular($query)
    {
        return $query->where('votes', '>', 100);
    }

    public function scopeWomen($query)
    {
        return $query->whereGender('W');
    }

}

$users = User::popular()->women()->orderBy('created_at')->get();
Run Code Online (Sandbox Code Playgroud)

Laravel Docs中雄辩的#scopes

  • IMO这应该是公认的答案,因为它特定于Laravel和Rubens的答案是正确的但不够具体. (2认同)

Ani*_*oin 6

TL; DR。您可以通过将查询表示为MyModel::query()->find(10);来解决此问题MyModel::find(10);

据我所知,从PhpStorm 2017.2代码检查失败的方法,如MyModel::where()MyModel::find()等(检查此线程)。这可能会很烦人,当您尝试在提交代码之前尝试使用PhpStorm的Git集成时PhpStorm不会停止抱怨这些静态方法调用警告。

解决这一问题的一种优雅方法(IMOO)是在有意义的地方显式调用::query()。这将使您受益于免费的自动完成和良好的查询格式。

例子

检查抱怨静态方法调用的代码片段

$myModel = MyModel::find(10); // static call complaint

// another poorly formatted query with code inspection complaints
$myFilteredModels = MyModel::where('is_beautiful', true)
    ->where('is_not_smart', false)
    ->get();
Run Code Online (Sandbox Code Playgroud)

格式正确的代码,没有任何抱怨

$myModel = MyModel::query()->find(10);

// a nicely formatted query with no complaints
$myFilteredModels = MyModel::query()
    ->where('is_beautiful', true)
    ->where('is_not_smart', false)
    ->get();
Run Code Online (Sandbox Code Playgroud)

  • 一样的,我真的很喜欢这个答案。我一开始就不是 Facades 的忠实粉丝,而且 PhpStorm 并不直接支持它们,这一事实让我不太喜欢它们。`MyModel::query()` 非常清楚地说明了幕后发生的事情,同时也让 IDE 满意。 (2认同)