Зачем использовать статический метод в классе модели laravel PHP?

В PHP laravel у нас есть коды вроде

$user = User::find(1);
var_dump($user->name);

Я не говорю о том, как использовать метод find, я имею в виду, почему laravel использует статический метод? Не следует ли использовать статический метод для тестирования метода?

Будет ли лучше, если они будут разработаны с использованием singleton?

например.

$user = User::getInstance()->find(1);
var_dump($user->name);

Ответ 1

Unnawut имеет очень хороший ответ, однако я счел необходимым добавить дополнительные пояснения.

В вашем примере

$user = User::find(1);
var_dump($user->name);

Laravel не использует статический метод. Другой способ сделать это, который вы, вероятно, ищете, - это использовать инъекцию зависимостей, которую Laravel делает очень легко, потому что это можно сделать автоматически. Итак, в любом классе, в котором вы используете вашу модель User, вы должны настроить что-то подобное в конструкторе...

public function __construct(User $user)
{
    $this->user = $user;
}

И затем вы можете изменить свой код, чтобы не использовать статические привязки.

$user = $this->user->find(1);
var_dump($user->name);

Ответ 2

На самом деле, ваш пример очень похож на то, что Laravel делает за сценой. Когда вы выполняете User::find(), вы действительно запрашиваете новый экземпляр, либо экземпляр Collection, либо QueryBuilder.

Illuminate\Database\Eloquent\Model (ссылка):

public static function find($id, $columns = array('*'))
{
    if (is_array($id) && empty($id)) return new Collection;

    $instance = new static;

    return $instance->newQuery()->find($id, $columns);
}

В качестве дополнительной заметки вы также увидите другой способ использования статических методов в Laravel, например. Input::get(). Они называются фасадами.

Фасады обеспечивают "статический" интерфейс к классам, доступным в контейнере IoC приложения. Laravel "фасады" служат в качестве "статических прокси" для базовых классов в контейнере IoC, обеспечивая преимущество кратковременного выразительного синтаксиса сохраняя при этом большую тестируемость и гибкость, чем традиционные статические методы.

Когда пользователь ссылается на какой-либо статический метод на... фасаде, Laravel разрешает привязку кэша из контейнера IoC и запускает запрошенный метод (в данном случае get) против этого объекта.

Вы можете узнать больше о Larave Facades по адресу: http://laravel.com/docs/facades

Ответ 3

Это ограничило бы систему только одним Пользователем. Хотя метод find может быть статическим, класс User будет иметь другие методы и свойства, которых нет, вероятный пример приведен в вашем примере: $user->name

Метод, который не полагается на какие-либо переменные экземпляра, переменные I.e, значение которых специфично для конкретного экземпляра объекта, но вместо этого предоставляет общие функции, применимые ко всем экземплярам, ​​может и, вероятно, должно быть статическим. Вот почему оператор $this является незаконным в статических методах, поскольку он не может ссылаться на конкретный экземпляр объекта.

Ответ 4

Следуя шаблонам GRASP, пользовательский объект не обладает знаниями для поиска пользователя.

Вам нужен объект Filter или Collection, метод ::find() поможет вам создать этот фильтр Collection и передать результат в полезный объект.

Для использования объекта User вы просто измените значение свойств и получите значения. Предприятие не несет ответственности за поиск экземпляров на основе условий.

С помощью этой логики вы сможете отделить логику от кода в атомных кусках.