web-dev-qa-db-fra.com

Pourquoi j'obtiens «La méthode non statique ne doit pas être appelée de manière statique» lors de l'appel d'une méthode dans un modèle Eloquent?

J'essaie de charger mon modèle dans mon contrôleur et j'ai essayé ceci:

return Post::getAll();

a obtenu l'erreur Non-static method Post::getAll() should not be called statically, assuming $this from incompatible context

La fonction dans le modèle ressemble à ceci:

public function getAll()
{

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

}

Quelle est la bonne façon de charger le modèle dans un contrôleur, puis de renvoyer son contenu?

62
Sam Pettersson

Vous avez défini votre méthode comme non statique et vous essayez de l'invoquer comme statique. Cela dit...

  1. ... si vous voulez invoquer une méthode statique, utilisez le :: et définissez votre méthode comme statique.

    // Defining a static method in a Foo class.
    public static function getAll() { /* code */ }
    
    // Invoking that static method
    Foo::getAll();
    
  2. ... sinon, si vous voulez appeler une méthode d'instance, vous devez instancier votre classe, utilisez ->.

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

Note: Dans Laravel, presque toutes les méthodes Eloquent renvoient une instance de votre modèle, ce qui vous permet d'enchaîner les méthodes comme indiqué ci-dessous:

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

Dans ce code, nous appelons statiquement la méthode all via Facade. Après cela, toutes les autres méthodes sont appelées comme méthodes d'instance .

76
Rubens Mariuzzo

Pourquoi ne pas essayer d'ajouter Scope? La portée est une très bonne caractéristique de 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

27
keithics

TL; DR . Vous pouvez contourner ce problème en exprimant vos requêtes sous la forme MyModel::query()->find(10); au lieu de MyModel::find(10);.

Au meilleur de ma connaissance, le démarrage de PhpStorm 2017.2 l'inspection de code échoue pour des méthodes telles que MyModel::where(), MyModel::find(), etc. (vérifiez ceci fil ). Cela peut devenir assez gênant lorsque vous essayez d'utiliser l'intégration de Git dans PhpStorm avant de valider votre code, PhpStorm n'arrête pas de vous plaindre de cet appel de méthode statique avertissements.

Un moyen élégant (IMOO) de contourner ce problème consiste à appeler explicitement ::query() partout où cela a du sens. Cela vous permettra de bénéficier d'une complétion gratuite et d'un formatage de requête Nice.

Exemples

Extrait où l'inspection se plaint d'appels de méthode statiques

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

Code bien formaté sans plaintes

$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

Juste au cas où cela aiderait quelqu'un, j'obtiendrais cette erreur parce que j'ai complètement manqué le fait déclaré que le préfixe de portée ne doit pas être utilisé lors de l'appel d'une portée locale. Donc, si vous définissez une portée locale dans votre modèle, procédez comme suit:

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

Vous devriez l'appeler comme ceci:

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

Notez que le préfixe scope n'est pas présent dans l'appel.

3
dotNET

Je viens littéralement d'arriver à la réponse dans mon cas. Je crée un système qui a implémenté une méthode de création. J'obtenais donc cette erreur car j'accédais à la version remplacée, pas à celle d'Eloquent.

J'espère que cette aide?

0
idro2k

Tu peux donner comme ça

public static function getAll()
{

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

}

Et lorsque vous appelez de manière statique dans la fonction de votre contrôleur également ...

0
Karthiga

Pour utiliser la syntaxe comme return Post::getAll();, vous devriez avoir une fonction magique __callStatic dans votre classe où gérer tous les appels statiques:

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

Vérifiez si vous n'avez pas déclaré la méthode getAll () dans le modèle. Cela fait penser au contrôleur que vous appelez une méthode non statique.

0