Почему я получаю "Нестатический метод не следует называть статически" при вызове метода в модели 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();
}
Какой правильный способ загрузить модель в контроллер, а затем вернуть ее?
Ответы
Ответ 1
Вы определили свой метод как нестатический, и вы пытаетесь вызвать его как статический. Тем не менее...
-
... если вы хотите вызвать статический метод, вы должны использовать ::
и определить свой метод как статический.
// Defining a static method in a Foo class.
public static function getAll() { /* code */ }
// Invoking that static method
Foo::getAll();
-
... в противном случае, если вы хотите вызвать метод экземпляра, вы должны указать свой класс, используйте ->
.
// 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();
В этом коде мы статически вызываем метод all
через Facade. После этого все другие методы называются методами экземпляра.
Ответ 2
Почему бы не попробовать добавить область? Область применения - очень хорошая особенность 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
Ответ 3
TL; DR. Вы можете обойти это, выразив свои запросы как MyModel::query()->find(10);
вместо MyModel::find(10);
.
Насколько мне известно, запуск проверки кода PhpStorm 2017.2 завершается неудачно для таких методов, как MyModel::where()
, MyModel::find()
и т.д. (Проверьте эту ветку). Это может раздражать, если вы попробуете, скажем, использовать интеграцию PhpStorm Git перед фиксацией кода, PhpStorm не перестанет жаловаться на эти предупреждения о вызовах статических методов.
Один из элегантных способов (IMOO) обойти это - явно вызывать ::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();
Ответ 4
На всякий случай, если это кому-то поможет, я получил эту ошибку, потому что я полностью пропустил указанный факт, что префикс области не должен использоваться при вызове локальной области. Так что, если вы определили локальную область в своей модели следующим образом:
public function scopeRecentFirst($query)
{
return $query->orderBy('updated_at', 'desc');
}
Вы должны назвать это как:
$CurrentUsers = \App\Models\Users::recentFirst()->get();
Обратите внимание, что префикс scope
отсутствует в вызове.
Ответ 5
Вы можете дать как это
public static function getAll()
{
return $posts = $this->all()->take(2)->get();
}
И когда вы вызываете статически внутри своей функции контроллера также.
Ответ 6
Я буквально только что пришел к ответу в моем случае.
Я создаю систему, которая реализовала метод create, поэтому я получил эту фактическую ошибку, потому что я обращался к переопределенной версии, а не к Eloquent.
Надеюсь, что поможет?
Ответ 7
Проверьте, не объявили ли вы метод getAll() в модели. Это заставляет диспетчера думать, что вы вызываете нестатический метод.
Ответ 8
Для использования такого синтаксиса, как return Post::getAll();
, в вашем классе должна быть магическая функция __callStatic
, где обрабатываются все статические вызовы:
public static function __callStatic($method, $parameters)
{
return (new static)->$method(...$parameters);
}