web-dev-qa-db-ja.com

Eloquentモデルでメソッドを呼び出すときに「非静的メソッドを静的に呼び出さないでください」と表示されるのはなぜですか?

私のモデルをコントローラーにロードしようとして、これを試しました:

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

}

モデルをコントローラーにロードし、その内容を返す正しい方法は何ですか?

62
Sam Pettersson

メソッドを非静的として定義し、静的として起動しようとしています。とはいえ...

  1. ...静的メソッドを呼び出す場合は、::を使用して、メソッドを静的として定義する必要があります。

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

そのコードでは、staticallyFacadeを介してallメソッドを呼び出しています。その後、他のすべてのメソッドは、インスタンスメソッドとして呼び出されます。

76
Rubens Mariuzzo

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

Laravel Docsの雄弁な#scopes

27
keithics

TL; DR。これを回避するには、クエリをMyModel::query()->find(10);ではなくMyModel::find(10);として表現します。

私の知る限り、PhpStorm 2017.2コード検査を開始すると、MyModel::where()MyModel::find()などのメソッドで失敗します(これを確認してください thread )。コードをコミットする前にPhpStormのGit統合を使用しようとすると、PhpStormは停止しません。これらの静的メソッド呼び出しの警告について不平を言う。

これを回避するエレガントな方法(IMOO)の1つは、意味のあるところならどこでも::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();

苦情のない適切にフォーマットされたコード

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

これが誰かを助ける場合に備えて、ローカルスコープを呼び出すときにスコーププレフィックスを使用してはならないという stated fact を完全に見逃していたため、このエラーが発生していました。したがって、モデルでローカルスコープを次のように定義した場合:

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

次のように呼び出す必要があります。

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

接頭辞scopeは呼び出しに存在しないことに注意してください。

3
dotNET

私の場合、文字通り答えにたどり着きました。 createメソッドを実装したシステムを作成しているので、Eloquentのものではなく、オーバーライドされたバージョンにアクセスしていたため、この実際のエラーが発生していました。

それが役立つことを願っていますか?

0
idro2k

このように与えることができます

public static function getAll()
{

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

}

また、コントローラー関数内で静的に呼び出す場合も..

0
Karthiga

return Post::getAll();のような構文を使用するには、クラスにすべての静的呼び出しを処理するマジック関数__callStaticが必要です。

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

モデルでメソッドgetAll()を宣言していないかどうかを確認してください。これにより、コントローラーは非静的メソッドを呼び出していると判断します。

0