Próbuję załadować mój model do mojego kontrolera i wypróbowałem to:
return Post::getAll();
otrzymałem błąd Non-static method Post::getAll() should not be called statically, assuming $this from incompatible context
Funkcja w modelu wygląda następująco:
public function getAll()
{
return $posts = $this->all()->take(2)->get();
}
Jaki jest właściwy sposób załadowania modelu do kontrolera, a następnie zwrócenia jego zawartości?
$obj->getAll()
lub ustaw funkcję statyczną.::
próbujesz uzyskać dostęp do metody statycznie tak podpis funkcja powinna zostać uznana jako:public static function getAll()
.Odpowiedzi:
Zdefiniowałeś swoją metodę jako niestatyczną i próbujesz wywołać ją jako statyczną. To mówi...
1. jeśli chcesz wywołać metodę statyczną, powinieneś użyć
::
i zdefiniować swoją metodę jako statyczną.// Defining a static method in a Foo class. public static function getAll() { /* code */ } // Invoking that static method Foo::getAll();
2. w przeciwnym razie, jeśli chcesz wywołać metodę instancji, powinieneś instancję swoją klasę, użyj
->
.// Defining a non-static method in a Foo class. public function getAll() { /* code */ } // Invoking that non-static method. $foo = new Foo(); $foo->getAll();
Uwaga : w Laravel prawie wszystkie metody Eloquent zwracają instancję modelu, co pozwala łączyć metody w łańcuch, jak pokazano poniżej:
$foos = Foo::all()->take(10)->get();
W tym kodzie statycznie wywołujemy
all
metodę poprzez Facade. Następnie wszystkie inne metody są wywoływane jako metody instancji .źródło
In Laravel, almost all Eloquent methods are defined as static
.... to błędne przekonanie. ŻADNE nie są statyczne.Dlaczego nie spróbować dodać zakresu? Zakres jest bardzo dobrą cechą 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();
Elokwentne #scopes w Laravel Docs
źródło
TL; DR . Możesz obejść ten problem, wyrażając swoje zapytania jako
MyModel::query()->find(10);
zamiastMyModel::find(10);
.Do mojej najlepszej wiedzy, począwszy PhpStorm 2017,2 inspekcja kodu nie powiedzie się metodami, takimi jak
MyModel::where()
,MyModel::find()
itp (sprawdź ten wątek ). Może to być dość denerwujące, gdy spróbujesz, powiedzmy, użyć integracji PhpStorm z Git przed zatwierdzeniem kodu, PhpStorm nie przestanie narzekać na te statyczne ostrzeżenia wywołań metod.Jednym eleganckim sposobem (IMOO) na obejście tego jest jawne wywołanie
::query()
wszędzie tam, gdzie ma to sens. Pozwoli to skorzystać z bezpłatnego automatycznego uzupełniania i ładnego formatowania zapytań.Przykłady
Fragment, w którym inspekcja skarży się na wywołania metod statycznych
$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();
Dobrze sformatowany kod bez reklamacji
$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();
źródło
MyModel::query()
bardzo jasno pokazuje, co dzieje się pod maską, jednocześnie zadowalając IDE.Na wszelki wypadek, gdyby to komuś pomogło, otrzymywałem ten błąd, ponieważ całkowicie przeoczyłem stwierdzony fakt, że prefiks zakresu nie może być używany podczas wywoływania zakresu lokalnego. Więc jeśli zdefiniowałeś lokalny zakres w swoim modelu w następujący sposób:
public function scopeRecentFirst($query) { return $query->orderBy('updated_at', 'desc'); }
Powinieneś to nazwać tak:
$CurrentUsers = \App\Models\Users::recentFirst()->get();
Zauważ, że przedrostek
scope
nie jest obecny w wywołaniu.źródło
Możesz tak dawać
public static function getAll() { return $posts = $this->all()->take(2)->get(); }
A kiedy dzwonisz statycznie wewnątrz funkcji kontrolera, również ...
źródło
Dosłownie właśnie dotarłem do odpowiedzi w moim przypadku. Tworzę system, w którym zaimplementowano metodę tworzenia, więc otrzymywałem ten rzeczywisty błąd, ponieważ uzyskiwałem dostęp do wersji zastąpionej, a nie z Eloquent.
Mam nadzieję, że to pomoże?
źródło
Sprawdź, czy nie zadeklarowałeś metody getAll () w modelu. To powoduje, że kontroler myśli, że wywołujesz metodę niestatyczną.
źródło
Aby użyć składni, tak jak
return Post::getAll();
powinieneś mieć__callStatic
w swojej klasie magiczną funkcję, która obsługuje wszystkie statyczne wywołania:public static function __callStatic($method, $parameters) { return (new static)->$method(...$parameters); }
źródło
Rozwiązanie pierwotnego pytania
Wywołałeś statyczną metodę statyczną. Aby uczynić funkcję publiczną statyczną w modelu, wyglądałoby to następująco:
public static function { }
Ogólnie:
W tym konkretnym przypadku:
Post::take(2)->get()
Jedną rzeczą, na którą należy uważać podczas definiowania relacji i zakresu, z którymi miałem problem, który spowodował błąd `` metody niestatycznej nie powinna być wywoływana statycznie '', jest sytuacja, gdy mają taką samą nazwę, na przykład:
public function category(){ return $this->belongsTo('App\Category'); } public function scopeCategory(){ return $query->where('category', 1); }
Kiedy wykonuję następujące czynności, pojawia się błąd niestatyczny:
Problem polega na tym, że Laravel używa mojej metody relacji o nazwie category, a nie mojego zakresu kategorii (scopeCategory). Można to rozwiązać, zmieniając nazwę zakresu lub relacji. Zdecydowałem się zmienić nazwę relacji:
public function cat(){ return $this->belongsTo('App\Category', 'category_id'); }
Zauważ, że zdefiniowałem klucz obcy (category_id), ponieważ w przeciwnym razie Laravel szukałby zamiast tego cat_id i nie znalazłby go, ponieważ zdefiniowałem go jako category_id w bazie danych.
źródło