php 为什么在调用 Eloquent 模型中的方法时出现“不应静态调用非静态方法”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18339716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 17:21:46  来源:igfitidea点击:

Why I'm getting 'Non-static method should not be called statically' when invoking a method in a Eloquent model?

phplaraveleloquent

提问by Sam Pettersson

Im trying to load my model in my controller and tried this:

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

return Post::getAll();

got the error Non-static method Post::getAll() should not be called statically, assuming $this from incompatible context

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

The function in the model looks like this:

模型中的函数如下所示:

public function getAll()
{

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

}

What's the correct way to load the model in a controller and then return it's contents?

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

回答by Rubens Mariuzzo

You defined your method as non-static and you are trying to invoke it as static. That said...

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

1.if you want to invoke a static method, you should use the ::and define your method as static.

1.如果你想调用一个静态方法,你应该使用::并将你的方法定义为静态。

// Defining a static method in a Foo class.
public static function getAll() { /* code */ }

// Invoking that static method
Foo::getAll();

2.otherwise, if you want to invoke an instance method you should instance your class, use ->.

2.否则,如果你想调用一个实例方法,你应该实例化你的类,使用->.

// Defining a non-static method in a Foo class.
public function getAll() { /* code */ }

// Invoking that non-static method.
$foo = new Foo();
$foo->getAll();

Note: In Laravel, almost all Eloquent methods return an instance of your model, allowing you to chain methods as shown below:

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

$foos = Foo::all()->take(10)->get();

In that code we are staticallycalling the allmethod via Facade. After that, all other methods are being called as instance methods.

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

回答by keithics

Why not try adding Scope? Scope is a very good feature of Eloquent.

为什么不尝试添加范围?作用域是 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();

Eloquent #scopes in Laravel Docs

Laravel 文档中的 Eloquent #scopes

回答by Anis

TL;DR. You can get around this by expressing your queries as MyModel::query()->find(10);instead of MyModel::find(10);.

TL;博士。您可以通过将查询表达为MyModel::query()->find(10);而不是 来解决此问题MyModel::find(10);

To the best of my knowledge, starting PhpStorm 2017.2code inspection fails for methods such as MyModel::where(), MyModel::find(), etc (check this thread). This could get quite annoying, when you try let's say to use PhpStorm's Git integrationbefore committing your code, PhpStormwon't stop complaining about these static method call warnings.

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

One elegant way (IMOO) to get around this is to explicitly call ::query()wherever it makes sense to. This will let you benefit from a free auto-completion and a nice query formatting.

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

Examples

例子

Snippet where inspection complains about static method calls

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

$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();

Well formatted code with no complaints

格式良好的代码,没有抱怨

$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();

回答by dotNET

Just in case this helps someone, I was getting this error because I completely missed the stated factthat the scope prefix must not be used when calling a local scope. So if you defined a local scope in your model like this:

以防万一这对某人有帮助,我收到此错误是因为我完全错过了在调用本地范围时不得使用范围前缀的陈述事实。因此,如果您在模型中定义了一个局部范围,如下所示:

public function scopeRecentFirst($query)
{
    return $query->orderBy('updated_at', 'desc');
}

You should call it like:

你应该这样称呼它:

$CurrentUsers = \App\Models\Users::recentFirst()->get();

Note that the prefix scopeis not present in the call.

请注意,scope呼叫中不存在前缀。

回答by Karthiga

You can give like this

你可以这样给

public static function getAll()
{

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

}

And when you call statically inside your controller function also..

当你在你的控制器函数中静态调用时..

回答by idro2k

I've literally just arrived at the answer in my case. I'm creating a system that has implemented a create method, so I was getting this actual error because I was accessing the overridden version not the one from Eloquent.

在我的案例中,我实际上刚刚得到了答案。我正在创建一个实现了 create 方法的系统,所以我收到了这个实际错误,因为我访问的是被覆盖的版本,而不是来自 Eloquent 的版本。

Hope that help?

希望有帮助?

回答by Julio Gonzalez Rios

Check if you do not have declared the method getAll() in the model. That causes the controller to think that you are calling a non-static method.

检查您是否没有在模型中声明 getAll() 方法。这会导致控制器认为您正在调用非静态方法。

回答by SpinyMan

For use the syntax like return Post::getAll();you should have a magic function __callStaticin your class where handle all static calls:

对于使用语法,return Post::getAll();您应该__callStatic在类中使用一个魔法函数来处理所有静态调用:

public static function __callStatic($method, $parameters)
{
    return (new static)->$method(...$parameters);
}