laravel 为什么我在调用Eloquent模型中的方法时会得到“不应静态调用非静态方法”?

o7jaxewo  于 2023-01-14  发布在  其他
关注(0)|答案(9)|浏览(129)

我试图加载我的模型在我的控制器,并尝试了这一点:

return Post::getAll();

得到错误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();

}

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

fcwjkofz

fcwjkofz1#

你可以这样给予

public static function getAll()
{

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

}

当你在你的控制器函数内部静态调用的时候..

gjmwrych

gjmwrych2#

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

qncylg1j

qncylg1j3#

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

gcxthw6b

gcxthw6b4#

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

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

x0fgdtte5#

你把你的方法定义为非静态的,而你试图把它作为静态的来调用。
1.如果你想调用一个静态方法,你应该使用::并将你的方法定义为static。

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

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

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

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

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

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

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

在这段代码中,我们通过Facade静态地调用all方法,之后,所有其他方法都作为示例方法调用。

dgenwo3n

dgenwo3n6#

为什么不试着加上范围呢?范围是口才的一个很好的特点。

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

iqjalb3h

iqjalb3h7#

    • TL; DR**。您可以通过将查询表示为MyModel::query()->find(10);而不是MyModel::find(10);来解决这个问题。

据我所知,启动 * PhpStorm 2017.2 * 代码检查对于MyModel::where()MyModel::find()等方法(检查此thread)失败,这可能会非常烦人。
一个(优雅的)解决方法是显式调用::query(),这将使您受益于 * 免费的自动完成 * 和良好的 * 格式化/缩进 * 查询。

示例

糟糕

检查报告静态方法调用的代码段

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

// another poorly formatted query with code inspection complaints
$myFilteredModels = MyModel::where('is_foo', true)
    ->where('is_bar', false)
    ->get();


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

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

// a nicely formatted and indented query with no complaints
$myFilteredModels = MyModel::query()
    ->where('is_foo', true)
    ->where('is_bar', false)
    ->get();
xcitsw88

xcitsw888#

以防万一这对某些人有帮助,我之所以得到这个错误,是因为我完全忽略了一个事实,即调用局部作用域时不能使用作用域前缀。因此,如果你在模型中定义了一个局部作用域,如下所示:

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

你应该这样称呼它:

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

注意,前缀scope在调用中不存在。

gwbalxhn

gwbalxhn9#

原问题的解答

你静态地调用了一个非静态的方法。要使一个公共函数在模型中成为静态的,看起来像这样:

public static function {
  
}

一般情况:

Post::get()

在这个特殊的例子中:

Post::take(2)->get()

在定义关系和作用域时,有一件事需要小心,我遇到了一个问题,导致了“不应静态调用非静态方法”错误,那就是当它们命名相同时,例如:

public function category(){
    return $this->belongsTo('App\Category');
}

public function scopeCategory(){
    return $query->where('category', 1);
}

当我执行以下操作时,我得到了非静态错误:

Event::category()->get();

问题是Laravel使用的是我的category关系方法,而不是我的category作用域(scopeCategory)。这可以通过重命名作用域或关系来解决。我选择重命名关系:

public function cat(){
    return $this->belongsTo('App\Category', 'category_id');
}

请注意,我定义了外键(category_id),因为否则Laravel将查找cat_id,但它不会找到它,因为我在数据库中将其定义为category_id。

相关问题