Warum erhalte ich „Nicht statische Methode sollte nicht statisch aufgerufen werden“, wenn ich eine Methode in einem Eloquent-Modell aufrufe?

Lesezeit: 7 Minuten

Benutzer-Avatar
Sam Petterson

Ich versuche, mein Modell in meinen Controller zu laden und habe Folgendes versucht:

return Post::getAll();

habe den Fehler bekommen Non-static method Post::getAll() should not be called statically, assuming $this from incompatible context

Die Funktion im Modell sieht so aus:

public function getAll()
{

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

}

Was ist der richtige Weg, um das Modell in einen Controller zu laden und dann seinen Inhalt zurückzugeben?

  • 2 Wege. 1. Erstellen Sie eine Instanz des Modells und verwenden Sie es $obj->getAll() oder machen Sie die Funktion statisch.

    – Itachi

    20. August 2013 um 16:14 Uhr

  • Wenn Sie verwenden: :: Sie versuchen, auf eine Methode zuzugreifen statisch Ihre Funktionssignatur sollte also wie folgt deklariert werden: public static function getAll().

    – Rubens Mariuzzo

    20. August 2013 um 18:12 Uhr


  • @Sam, ich empfehle Ihnen eine fünfminütige Lektüre über OOP- und statische Methoden in PHP: php.net/manual/en/language.oop5.static.php

    – Rubens Mariuzzo

    20. August 2013 um 18:30 Uhr

Benutzer-Avatar
Rubens Mariuzzo

Sie haben Ihre Methode als nicht statisch definiert und versuchen, sie als statisch aufzurufen. Das gesagt…

1. Wenn Sie eine statische Methode aufrufen möchten, sollten Sie die verwenden :: und definieren Sie Ihre Methode als statisch.

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

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

2. andernfalls, wenn Sie eine Instanzmethode aufrufen möchten, sollten Sie Ihre Klasse instanziieren, verwenden ->.

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

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

Notiz: In Laravel geben fast alle Eloquent-Methoden eine Instanz Ihres Modells zurück, sodass Sie Methoden wie unten gezeigt verketten können:

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

In diesem Code sind wir statisch Aufruf der all Methode über Fassade. Danach werden alle anderen Methoden als aufgerufen Instanzmethoden.

  • Wie ist getAll() in der 2. Option nicht statisch?

    – Sich selbst versuchen

    20. August 2013 um 19:58 Uhr


  • Danke @TryingTobemyself, dass du mich darüber benachrichtigst. Ich habe meine Antwort mit Ihrem Vorschlag aktualisiert.

    – Rubens Mariuzzo

    20. August 2013 um 20:58 Uhr

  • In Laravel, almost all Eloquent methods are defined as static…. das ist ein Irrglaube. KEINER sind statisch.

    – Itachi

    21. August 2013 um 1:38 Uhr


  • Ja, in Laravel sind keine Eloquent-Methoden als statisch definiertwir können verwenden Sie sind sozusagen statisch definiert, aber das ist eine Fassade, mehr dazu: laravel.com/docs/facades

    – Rubens Mariuzzo

    9. Juli 2014 um 15:49 Uhr

  • Obwohl die Antwort sachlich ist, ist es im Kontext von Laravel unwahrscheinlich, dass dies die Lösung ist, nach der Benutzer in diesem Thread suchen. Diese Antwort sollte entfernt und die Antwort von keithics als richtig markiert werden.

    – Nullen und Einsen

    2. Dezember 2016 um 18:02 Uhr

Benutzer-Avatar
Keithik

Warum versuchen Sie nicht, Scope hinzuzufügen? Scope ist ein sehr gutes Feature von 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

  • IMO sollte dies die akzeptierte Antwort sein, da sie spezifisch für Laravel ist und Rubens Antwort richtig, aber nicht spezifisch genug ist.

    – JacobRossDev

    13. März 2015 um 18:15 Uhr

  • @JacobRossDev Ich verwende den Bereich, das erste Mal, als ich den lokalen Bereich verwendete und richtig arbeitete, erstellte ich den globalen Bereich, wenn mein Bedarf nicht erfüllt wird. Ich komme zurück zum lokalen Bereich, dem ich alle Namenskonventionen folge, aber beim Aufrufen bekomme ich den Fehler von BadMethodCallException Aufruf der undefinierten Methode App\Models\Share::popular()

    – MANSOOR KOCHY

    2. März um 6:43

  • Ich habe scope und bekam diesen Fehler (weil beides vorhanden war published() und scopePublished() definiert). Lösung war zu tun: Post::query()->published(); Anstatt von Post::published();

    – Top-Master

    1. April um 14:14 Uhr


Benutzer-Avatar
Anis LOUNIS alias AnixPasBesoin

TL;DR. Sie können dies umgehen, indem Sie Ihre Abfragen als ausdrücken MyModel::query()->find(10); Anstatt von MyModel::find(10);.

Meines Wissens nach ab PHPStorm 2017.2 Die Codeinspektion schlägt bei Methoden wie z MyModel::where(), MyModel::find()etc (überprüfen Sie dies Faden). Dies könnte ziemlich ärgerlich werden, wenn Sie (sagen wir) versuchen, es zu verwenden Git-Integration von PhpStorm bevor Sie Ihren Code übertragen, PhpSturm wird nicht aufhören, sich über diese statischen Methodenaufrufwarnungen zu beschweren.

Eine elegante Möglichkeit (IMOO), dies zu umgehen, ist ausdrücklich anrufen ::query() wo es Sinn macht. Davon profitieren Sie kostenlose automatische Vervollständigung und ein nettes Formatierung für Ihre Anfragen.

Beispiele

SCHLECHT

Ausschnitt, in dem sich die Inspektion über statische Methodenaufrufe beschwert

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

GUT

Gut formatierter Code ohne Beschwerden

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

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

  • Code ändern, nur um eine zu entfernen falsch IDE-Warnung klingt wie eine schlechte Idee. Wenn du weißt, dass es richtig ist, dann behalte es so.

    – Zundi

    19. Juli 2018 um 23:08 Uhr

  • @zundi Ja, Sir, ich stimme voll und ganz zu, dass das Ändern von Code zum Wohle der IDE nicht immer eine gute Praxis ist. ABER In diesem Fall fügen wir nur einen statischen Methodenaufruf hinzu, der auf beide Arten aufgerufen worden wäre (wir sind hier nur explizit). Andernfalls müssten Sie: entweder diese Inspektion deaktivieren oder eine andere Klasse an anderer Stelle kommentieren … (eine Hektik! stimmen Sie nicht zu?)

    – Anis LOUNIS alias AnixPasBesoin

    20. Juli 2018 um 23:56 Uhr


  • Gleich, ich mag diese Antwort wirklich. Ich bin zunächst kein großer Fan von Facades, und die Tatsache, dass PhpStorm sie nicht sofort unterstützt, lässt mich sie weniger mögen. MyModel::query() macht sehr deutlich, was unter der Haube passiert, und erfreut gleichzeitig die IDE.

    – Michasaurus

    23. Juli 2019 um 19:22 Uhr

Nur für den Fall, dass dies jemandem hilft, ich habe diesen Fehler erhalten, weil ich das komplett verpasst habe festgestellte Tatsache dass das Bereichspräfix beim Aufrufen eines lokalen Bereichs nicht verwendet werden darf. Wenn Sie also in Ihrem Modell einen lokalen Bereich wie folgt definiert haben:

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

Du solltest es so nennen:

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

Beachten Sie, dass das Präfix scope ist im Anruf nicht vorhanden.

Lösung der ursprünglichen Frage

Sie haben eine nicht statische Methode statisch aufgerufen. Um eine öffentliche Funktion im Modell statisch zu machen, würde das so aussehen:

public static function {
  
}

Im Algemeinen:

Post::get()

In diesem speziellen Fall:

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

Eine Sache, auf die Sie beim Definieren von Beziehungen und Umfang achten müssen, mit der ich ein Problem hatte, das einen Fehler „nicht statische Methode sollte nicht statisch aufgerufen werden“ verursachte, ist, wenn sie gleich benannt sind, zum Beispiel:

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

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

Wenn ich Folgendes mache, erhalte ich den nicht statischen Fehler:

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

Das Problem ist, dass Laravel meine Beziehungsmethode namens category verwendet und nicht meinen Kategoriebereich (scopeCategory). Dies kann durch Umbenennen des Bereichs oder der Beziehung behoben werden. Ich habe mich entschieden, die Beziehung umzubenennen:

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

Bitte beachten Sie, dass ich den Fremdschlüssel (category_id) definiert habe, da Laravel sonst stattdessen nach cat_id gesucht und ihn nicht gefunden hätte, da ich ihn als category_id in der Datenbank definiert hatte.

Benutzer-Avatar
Karthiga

Du kannst so geben

public static function getAll()
{

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

}

Und wenn Sie auch statisch innerhalb Ihrer Controller-Funktion aufrufen.

Benutzer-Avatar
idro2k

Ich bin buchstäblich gerade bei der Antwort in meinem Fall angekommen. Ich erstelle ein System, das eine Erstellungsmethode implementiert hat, daher habe ich diesen tatsächlichen Fehler erhalten, weil ich auf die überschriebene Version zugegriffen habe, nicht auf die von Eloquent.

Hoffe das hilft?

1355000cookie-checkWarum erhalte ich „Nicht statische Methode sollte nicht statisch aufgerufen werden“, wenn ich eine Methode in einem Eloquent-Modell aufrufe?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy