Как работает метод в моделях Laravel? - PullRequest
0 голосов
/ 02 марта 2019

Мы часто используем where метод с нашими моделями, но он не определен в классе базовой модели, так как laravel делает эту магию?

например, MyModel::where('id, 2)->get();

Выше, где определенно будетполучить запись с идентификатором равным 2, но где и как это происходит!Я проследил до базовой модели в Laravel, но не нашел метод где!

Ответы [ 2 ]

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

Часть этой магии находится за паттерном фасада https://www.tutorialspoint.com/design_pattern/facade_pattern.htm

Но в случае с Laravel они используют статические методы в своих фасадах (\Illuminate\Support\Facades пространство имен) и автоматически создают экземпляр для вызова этих методов из экземпляра.так что вам не нужно создавать экземпляр класса самостоятельно, чтобы начать использовать методы.Например, когда вы используете DB::, Cache::, Str:: для вызова статического метода.

Однако для Eloquent Laravel использует этот подход более внутренне, не подвергая модель пространству имен \Illuminate\Support\Facades, настраивая EloquentМодель автоматически создает экземпляр Модели и создает \Illuminate\Database\Eloquent\Builder Eloquent Builder и перенаправляет вызов этих статических методов в экземпляр Eloquent Builder или в экземпляр Query Builder.

Модель расширяет \Illuminate\Database\Eloquent\Model, в которой есть специальный способ вызова любогометод статически во время выполнения.

/**
 * Handle dynamic static method calls into the method.
 *
 * @param  string  $method
 * @param  array  $parameters
 * @return mixed
 */
public static function __callStatic($method, $parameters)
{
    return (new static)->$method(...$parameters);
}

Таким образом, в определенный момент класс Builder Eloquent использует черту

use Illuminate\Support\Traits\ForwardsCalls;

для переадресации вызова друг другу, чтобы модель могла переслать своюстатический метод к методу из созданного экземпляра Eloquent Builder.Поэтому, если модель не имеет where метода, она перенаправит его в метод where вновь созданного nstance Eloquent Builder.

Из взгляда на Facade Pattern, вот как Laravel вызывает метод изэкземпляр, но статическим образом:

// \Illuminate\Support\Facades\Facade.php
/**
 * Handle dynamic, static calls to the object.
 *
 * @param  string  $method
 * @param  array   $args
 * @return mixed
 *
 * @throws \RuntimeException
 */
public static function __callStatic($method, $args)
{
    $instance = static::getFacadeRoot();

    if (! $instance) {
        throw new RuntimeException('A facade root has not been set.');
    }

    return $instance->$method(...$args);
}

Таким образом, вызов User::where() создает экземпляр \Illuminate\Database\Eloquent\Builder и переадресацию вызова метода к этому экземпляру, вот метод:

// Illuminate\Database\Eloquent\Builder.php
/**
 * Add a basic where clause to the query.
 *
 * @param  string|array|\Closure  $column
 * @param  mixed   $operator
 * @param  mixed   $value
 * @param  string  $boolean
 * @return $this
 */
public function where($column, $operator = null, $value = null, $boolean = 'and')
{
    if ($column instanceof Closure) {
        $column($query = $this->model->newModelQuery());

        $this->query->addNestedWhereQuery($query->getQuery(), $boolean);
    } else {
        $this->query->where(...func_get_args());
    }

    return $this;
}
0 голосов
/ 02 марта 2019

Вы можете найти метод здесь .framework/src/Illuminate/Database/Eloquent/Builder.php

public function where($column, $operator = null, $value = null, $boolean = 'and')
    {
        if ($column instanceof Closure) {
            $column($query = $this->model->newModelQuery());
            $this->query->addNestedWhereQuery($query->getQuery(), $boolean);
        } else {
            $this->query->where(...func_get_args());
        }
        return $this;
    }

Дополнительная информация об этом

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