Laravel имеет имя столбца в статическом методе предложения where

Недавно я только что понял, что Laravel генерирует статический метод с именем столбца при объединении в предложении where с использованием случая верблюда.

пример

$user = User::whereName('john')->first(); // added `name` as a column name

При вызове этого кода в SQL он генерирует

$user = User::whereName('john')->toSql();

//it returns
select * from `users` where `name` = ?

Это действительно дает ожидаемый результат, поскольку возвращает пользователя с именем john.

Я искал документацию Laravel, но не могу найти эту функцию или где она была определена.

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


person Emmanuel David    schedule 14.02.2020    source источник
comment
Это называется where магическим методом. Я нашел документацию laravel.com/docs/5.0/queries#selects Dynamic Where Clauses   -  person Amit Senjaliya    schedule 14.02.2020


Ответы (4)


Если вы спрашиваете, где находится код, отвечающий за его работу, он использует магический метод __call() (до этого __callStatic() для создания экземпляра) в классе Illuminate\Database\Query\Builder

/**
     * Handle dynamic method calls into the method.
     *
     * @param  string  $method
     * @param  array   $parameters
     * @return mixed
     *
     * @throws \BadMethodCallException
     */
    public function __call($method, $parameters)
    {
        if (static::hasMacro($method)) {
            return $this->macroCall($method, $parameters);
        }

        if (Str::startsWith($method, 'where')) {
            return $this->dynamicWhere($method, $parameters);
        }

        static::throwBadMethodCallException($method);
    }

именно в условии Str::startsWith($method, 'where') которые перенаправляют вызов на dynamicWhere()

/**
     * Handles dynamic "where" clauses to the query.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return $this
     */
    public function dynamicWhere($method, $parameters)
    {
        $finder = substr($method, 5);

        $segments = preg_split(
            '/(And|Or)(?=[A-Z])/', $finder, -1, PREG_SPLIT_DELIM_CAPTURE
        );

        // The connector variable will determine which connector will be used for the
        // query condition. We will change it as we come across new boolean values
        // in the dynamic method strings, which could contain a number of these.
        $connector = 'and';

        $index = 0;

        foreach ($segments as $segment) {
            // If the segment is not a boolean connector, we can assume it is a column's name
            // and we will add it to the query as a new constraint as a where clause, then
            // we can keep iterating through the dynamic method string's segments again.
            if ($segment !== 'And' && $segment !== 'Or') {
                $this->addDynamic($segment, $connector, $parameters, $index);

                $index++;
            }

            // Otherwise, we will store the connector so we know how the next where clause we
            // find in the query should be connected to the previous ones, meaning we will
            // have the proper boolean connector to connect the next where clause found.
            else {
                $connector = $segment;
            }
        }

        return $this;
    }
person N69S    schedule 14.02.2020
comment
Спасибо, это действительно решает мое желание знать, где определена функция и как она возвращает свое значение. - person Emmanuel David; 14.02.2020

Этот подход полностью законен, но плохо документирован. В Query\Builder он использует перезапись функции __call для создания функциональности, и вы можете увидеть точную функцию здесь.

Тема магических методов и функции __call часто вызывает большие споры, если они к лучшему. Если вы используете помощник IDE. Он на самом деле напечатает подсказки для вас и, таким образом, облегчит некоторые из магических подходов, которые он использует, и предоставит вам плавный опыт работы с IDE.

Пример сгенерированных подсказок типа из моего локального проекта.

* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\User whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\App\Models\User whereEmail($value)

Поэтому я бы не беспокоился, что это не лучший подход. Есть много способов делать то, что вы делаете, но этот — один из правильных.

person mrhn    schedule 14.02.2020

Попробуй это

$user = User::where('name','john')->first();
person Naeem Ijaz    schedule 14.02.2020
comment
Не то, что спрашивает ОП. - person Qumber; 14.02.2020
comment
Хотя этот код может решить проблему, включая объяснение того, как и почему это решает проблему, действительно поможет улучшить качество вашего сообщение и, вероятно, приведет к большему количеству голосов. Помните, что вы отвечаете на вопрос для будущих читателей, а не только для того, кто задает сейчас. Пожалуйста, отредактируйте свой ответ, чтобы добавить пояснения и указать, какие ограничения и предположения применяются. Из обзора - person double-beep; 14.02.2020

вам нужно определить эту функцию в вашей модели

//controller
$userObj=new \App\User();
$userObj->whereName('john');
//model
function whereName($name){
return $this->where('name',$name)->first();
}
person PHP Geek    schedule 14.02.2020