【问题标题】:How do query scopes work in Laravel?查询范围如何在 Laravel 中工作?
【发布时间】:2017-12-27 01:47:33
【问题描述】:

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

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

<?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()-&gt;where('id', '&gt;', 1)-&gt;get();

所以我不太确定这个变量是从哪里来的。

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

【问题讨论】:

    标签: php laravel oop eloquent


    【解决方案1】:

    这是相当广泛的,因为它涵盖了关于 Eloquent 的两个大主题。


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

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

    外观模式利用重载和魔术方法__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);
    }
    

    由于模型中没有定义 where() 或不完整(),它们将被传递给由 Model::newQuery() 返回的 Builder 类。

    在 Builder __call 方法中,您有:

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

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

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

    模型 __call() -> 构建器 __call() -> 模型范围不完整(构建器 $builder)

    【讨论】:

    • 感谢您在这些主题上为我指明正确的方向。看起来他们很大,我有很多学习要做。可能应该继续这个系列!
    • @TimothyFisher Jeffrey 可能不会像这样深入探讨。但是自己检查课程始终是了解兔子洞通向何处的好方法。 Eloquent 确实大量使用了重载,这是它的有效批评之一,但是重载的使用也使得语法非常具有表现力和易于使用。你不一定需要了解 Eloquent 如何完成任务的每一个细节,只要你了解如何使用它即可。
    猜你喜欢
    • 2018-10-02
    • 2017-12-17
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 2015-10-06
    相关资源
    最近更新 更多