该方法在Laravel模型中如何工作?

该方法在Laravel模型中如何工作?,laravel,laravel-5,eloquent,Laravel,Laravel 5,Eloquent,我们经常在模型中使用where方法,但它并没有在基本模型类中定义,所以laravel是如何做到这一点的 e、 gMyModel::where('id,2)->get() 上面的where肯定会获取id等于2的记录,但是where&这是如何发生的!我追溯到Laravel中的基本模型,但没有找到where方法 你可以找到方法framework/src/illumb/Database/elount/Builder.php public function where($column, $operator

我们经常在模型中使用
where
方法,但它并没有在基本模型类中定义,所以laravel是如何做到这一点的

e、 g
MyModel::where('id,2)->get()

上面的where肯定会获取id等于2的记录,但是where&这是如何发生的!我追溯到Laravel中的基本模型,但没有找到where方法

你可以找到方法
framework/src/illumb/Database/elount/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;
    }

这种魔力的一部分存在于门面图案背后

但在Laravel的例子中,他们在Facades(
\lightlight\Support\Facades
名称空间)中使用静态方法,并自动创建实例从实例调用这些方法,因此您不必亲自实例化类来开始使用这些方法。例如,当您使用
DB::
Cache::
Str::
调用静态方法时

然而,对于雄辩,Laravel在更内部地使用这种方法,而不将模型暴露于
\lighting\Support\Facades
名称空间,通过配置Eloquent Model来自动实例化模型,并创建
\illustration\Database\Eloquent\Builder
Eloquent Builder,并将这些静态方法调用转发给Eloquent Builder实例或查询Builder实例

模型扩展了
\illumb\Database\elount\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);
}
因此,在某一点上,构建器类会雄辩地使用一个特性

use Illuminate\Support\Traits\ForwardsCalls;
转发对彼此的调用,以便模型可以将其静态方法从创建的Eloquent builder实例转发到另一个方法。因此,如果模型没有
where
方法,它将把它转发给新创建的雄辩生成器实例的where方法

从外观模式来看,以下是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()
将创建
\illumb\Database\elount\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;
}

您共享的链接是关于生成器类的。我说的是基本模型类,即当我从模型扩展一个类时,例如MyClass扩展了模型。在本例中,请看这里:。
newCollection
方法返回一个集合实例(其中包含where方法),因此
newCollection
允许我们使用where方法吗?你能详细说明一下吗?我想是的,我在文档中搜索了很多,这就是我发现的。很抱歉没有准确的答案。您可以在此处查看集合类:。因此,在您的模型类中,您可以调用一个方法(newCollection),该方法返回一个集合,允许您使用要查找的where方法。我想就是这样,这意味着如果我调用
MyModel::test()
它将转到
\uu callStatic
方法,对吗?@Iftikharuddin您可以尝试
\uu callStatic()
中回显$method
,您会看到它