【问题标题】:Laravel closure, what is $query, how is $query passed?Laravel闭包,什么是$query,$query是怎么传的?
【发布时间】:2016-10-15 00:33:49
【问题描述】:

我不明白这个结构:

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

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

【问题讨论】:

    标签: php laravel closures


    【解决方案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 的新实例。

    【讨论】:

      【解决方案2】:

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

      Laravel 广泛使用基于闭包的类和调用,因为类可以被实例化、使用和丢弃而无需持久化。

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

          // 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();
                    });
          });
      

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

      在查询之外,队列和其他基于闭包的功能(例如 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

      【讨论】:

        猜你喜欢
        • 2022-01-22
        • 2021-09-04
        • 2018-05-04
        • 1970-01-01
        • 2014-01-23
        • 2019-01-02
        • 1970-01-01
        • 1970-01-01
        • 2017-10-08
        相关资源
        最近更新 更多