查询范围如何在Laravel中运行?

问题描述 投票:4回答:1

我正在看Scracch系列中的Laracasts:Laravel 5.4,并且遇到了查询范围的概念。

在视频中,我们设置了这样一个类:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{

    public function scopeIncomplete($query)
    {

        return $query->where('completed', 0);

    }
}

我的第一个问题:

为什么这样的方法如下:public function scopeIncomplete($query)这样调用:App\Task::incomplete()::运算符?

这不是静态调用的非静态方法吗?

我的第二个问题:

$query来自哪里?

根据我的理解,这是“现有”查询,但它被称为:App\Task::incomplete()->where('id', '>', 1)->get();

所以我不确定这个变量来自哪里。

也许它稍后会有更深入的解释,但我无法理解这是如何运作的。

php laravel oop eloquent
1个回答
3
投票

这是非常广泛的,因为它涵盖了Eloquent的两个大型主题。


第一个是指Eloquent使用Facade模式将静态调用传递给非静态方法。

Facade模式利用IoC容器将方法调用传递给类的绑定或新实例。

Facade模式使用重载和魔术方法__callStatic。


第二个问题涉及Eloquent的重载,它将未注册的方法调用传递给查询构建器对象(特别是\ Illuminate \ Database \ Eloquent \ Builder)。这允许在Eloquent模型本身上调用where()和各种其他Query Builder方法。在Model类中,您可以看到:

/**
 * Handle dynamic method calls into the model.
 *
 * @param  string  $method
 * @param  array  $parameters
 * @return mixed
 */
public function __call($method, $parameters)
{
    if (in_array($method, ['increment', 'decrement'])) {
        return $this->$method(...$parameters);
    }

    return $this->newQuery()->$method(...$parameters);
}

由于未在Model中定义where()或incomplete(),因此它们将被传递给Builder类,该类由Model :: newQuery()返回。

在Builder __call方法中,您有:

    if (method_exists($this->model, $scope = 'scope'.ucfirst($method))) {
        return $this->callScope([$this->model, $scope], $parameters);
    }

所以这是检查模型中定义的范围并传递包含此Builder实例的$参数。

总而言之,对Model :: incomplete()的调用将会:

Model __call() - > Builder __call() - > Model scopeIncomplete(Builder $ builder)

© www.soinside.com 2019 - 2024. All rights reserved.