Расширение Laravel create (): Почему в документах говорится, что нужно переопределить нестатический метод как статический? - PullRequest
0 голосов
/ 04 марта 2019

У меня есть проект Laravel, который я обновляю с 5.3 до 5.4, следуя Руководству по обновлению Laravel .

В руководстве говорится, что методы создания были перемещены вКласс Builder, и этот метод должен называться по-новому $model = static::query()->create($attributes);.Помимо того, что описано в руководстве по обновлению, в Интернете есть много вопросов, таких как здесь и здесь .

Часть, которую я не понимаю,почему они все еще определяют переопределяющий метод как статический.Новый метод create больше не является статическим (отсюда и новый вызов), но все примеры по-прежнему определяют статический метод для его переопределения.Если я это сделаю, PHPStorm выдаст мне следующую (ожидаемую) ошибку:

Невозможно сделать нестатический метод Builder-> create ([attribute: array = []]) static

Почему примеры (включая официальные документы) переопределяют это как статическое?

Если есть причина, по которой он работает для всех остальных, почему мой не работает?

1 Ответ

0 голосов
/ 09 марта 2019

Итак, вот очень краткое объяснение того, что здесь происходит.В красноречивой модели Laravel версии 5.3 и более ранних в качестве своего класса в качестве статической функции использовался метод create.Это был источник:

public static function create(array $attributes = [])
{
    $model = new static($attributes);
    $model->save();
    return $model;
}

В то же время модель имела следующее определение __call.

public function __call($method, $parameters)
{
    if (in_array($method, ['increment', 'decrement'])) {
        return $this->$method(...$parameters);
    }
    return $this->newQuery()->$method(...$parameters);
}

Это означало, что каждый вызов функции, который не был определен в моделибудет вызван для нового экземпляра объекта Builder.

В 5.4 они решили, что create выглядит лучше в Builder, чем в самой модели, поэтому они сделали этот метод там:

public function create(array $attributes = [])
{
    return tap($this->newModelInstance($attributes), function ($instance) {
        $instance->save();
    });
}

он, по сути, делает то же самое, но лучше подходит для компоновщика, однако заметное отличие состоит в том, что это не статично , потому что все статические вызовы в модели перенаправляются вBuilder экземпляр .

Если вы переопределили метод ранее в подклассах, а затем вызвали parent::create в какой-то момент, это, вероятно, больше не будет работать, поскольку родительский объект на самом деле не имел create, поэтому альтернативный код static::query()->create(...) былпредложил.На практике вызов $this->__call('create', ...) также, вероятно, сработает, но его очень сложно прочитать, и он может испортить IDE, выполняющие рефакторинг, потому что это необнаружимый вызов Builder::create.

Теперь последний бит - это Modelтакже имел @mixin Builder на нем.@mixin указывает, что класс в основном смешан с текущим классом для расширения его функциональности и используется, чтобы намекнуть IDE, что это происходит, когда это происходит нестандартными способами ООП (например, с __call и __callStatic вэтот случай).Это заставило вашу IDE подумать, что вы перегружаете create на Builder из-за того, что IDE считает, что Builder был смешан с Model, однако реальность такова, что это не совсем смешано, а скорее смешано вкак статика (насколько я знаю, у PhpStorm есть проблемы с этой концепцией)

Так что это так.Я надеюсь это имеет смысл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...