Laravel关闭,什么是$ query,$ query是如何通过的?

时间:2016-06-14 10:19:53

标签: php laravel closures

我不明白这个结构:

$posts = Post::where(function($query)
        {
            $query->where('title', 'LIKE', "%search%")
                  ->orWhere('body', 'LIKE', "%search%");
        });

该函数是否将$ query传递给自身?或者$ query是否代表在代码中其他地方实例化的对象?

2 个答案:

答案 0 :(得分:1)

如果您更深入了解Laravel源代码,您可以看到,当您将闭包传递给where的第一个参数时,它将被视为新的嵌套查询:

if ($column instanceof Closure) {
    return $this->whereNested($column, $boolean);
}

然后,只需使用call_user_func调用您的函数,并将Query Builder的新实例附加为第一个参数(query

$query = $this->newQuery();

$query->from($this->from);

call_user_func($callback, $query);

长话短说:您的$ query参数是Query Builder的新实例。

答案 1 :(得分:0)

在PHP中,闭包是“可手动绑定参数的可调用类”(引自http://php.net/manual/en/class.closure.php#117427)。

Laravel广泛使用基于Closure的类和调用,因为可以在不需要持久性的情况下实例化,使用和丢弃类。

考虑进一步使用(将“超出范围”变量传递给Closures):

    // This var would not get passed to the closure as it's "out of scope"
    $outOfScopeVar = [12,13,14];

    $posts = Post::where(function($query) use($outOfScopeVar)
    {
        $query->where('title', 'LIKE', "%search%")
              ->orWhere('body', 'LIKE', "%search%")
              ->whereIn('id', function ($query2) use ($outOfScopeVar) {
                  $query2->select('users_posts.posts_id')
                    ->from('users_posts')
                    ->whereIn('users_posts.users_id',$outOfScopeVar)
                    ->get();
              });
    });

在查询上下文中,您可以使用它来构建非常复杂但面向对象的查询。

在查询之外,队列和其他基于Closure的功能(如Mail构造)使用闭包来定义功能和范围,而不必列出所涉及的整个方法。例如,构造消息,附加任何文件,附加标题,渲染视图等都由与传递的闭包交互的背景方法处理。

您可以通过浏览文档来了解Mailer类如何与传递的闭包进行交互。

https://github.com/laravel/framework/blob/master/src/Illuminate/Mail/Mailer.php#L149

对于QueryBuilder:

https://github.com/laravel/framework/blob/43808e3b54973e9c18de01b7390f7d137fa38762/src/Illuminate/Database/Query/Builder.php