98 votes

Pourquoi est-ce que j'obtiens 'Non-static method should not be called statically' quand j'invoque 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();

J'ai 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 et de renvoyer son contenu ?

131voto

Rubens Mariuzzo Points 6022

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

1.Si vous souhaitez invoquer une méthode statique, vous devez utiliser la fonction :: 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.autrement, si vous voulez invoquer une méthode d'instance, vous devez instance votre classe, utiliser -> .

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

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

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

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

Dans ce code, nous sommes statiquement en appelant le all via Facade. Après cela, toutes les autres méthodes sont appelées en tant que méthodes d'instance .

45voto

keithics Points 1155

Pourquoi ne pas essayer d'ajouter Scope ? Scope est une très bonne fonctionnalité d'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();

Des #scopes éloquents dans les Docs de Laravel

8voto

Anix PasBesoin Points 2335

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

Pour autant que je sache, le démarrage PhpStorm 2017.2 l'inspection du code échoue pour des méthodes telles que MyModel::where() , MyModel::find() etc. (vérifiez ceci hilo ). Cela peut devenir assez ennuyeux, lorsque vous essayez (disons) d'utiliser la fonction Intégration de Git dans PhpStorm avant de valider votre code, PhpStorm n'arrête pas de se plaindre de ces avertissements d'appels de méthodes statiques.

Une façon élégante (IMOO) de contourner ce problème est de appeler explicitement ::query() partout où cela a un sens. Cela vous permettra de bénéficier autocomplétion gratuite et une belle mise en forme pour vos demandes de renseignements.

Exemples

MAUVAIS

Extrait où l'inspection se plaint des appels de méthodes statiques

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

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

BON

Code bien formaté, sans aucune plainte

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

// a nicely formatted query with no complaints
$myFilteredModels = MyModel::query()
    ->where('is_beautiful', true)
    ->where('is_smart', false)
    ->get();

3voto

dotNET Points 5290

Au cas où cela aiderait quelqu'un, j'ai eu cette erreur parce que j'ai complètement raté l'option fait établi que le préfixe de l'étendue ne doit pas être utilisé lors de l'appel d'une étendue locale. Donc si vous avez défini une portée locale dans votre modèle comme ceci :

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

Tu devrais l'appeler comme ça :

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

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

1voto

Darren Murphy Points 77

Solution à la question initiale

Vous avez appelé une méthode non statique de manière statique. Pour rendre une fonction publique statique dans le modèle, cela ressemblerait à ceci :

public static function {

}

En général :

Post::get()

Dans ce cas particulier :

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

Une chose à laquelle il faut faire attention, lors de la définition des relations et de la portée, et qui m'a posé problème en provoquant l'erreur "une méthode non statique ne doit pas être appelée de manière statique", c'est lorsqu'elles portent le même nom, par exemple :

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

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

Lorsque je fais ce qui suit, j'obtiens l'erreur non statique :

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

Le problème, c'est que Laravel utilise ma méthode de relation appelée category, plutôt que mon scope de catégorie (scopeCategory). Cela peut être résolu en renommant le scope ou la relation. J'ai choisi de renommer la relation :

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

Veuillez noter que j'ai défini la clé étrangère (category_id) car sinon Laravel aurait cherché cat_id à la place, et il ne l'aurait pas trouvé, car je l'avais défini comme category_id dans la base de données.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X