【问题标题】:How can I build a condition based query in Laravel?如何在 Laravel 中构建基于条件的查询?
【发布时间】:2012-12-20 05:26:14
【问题描述】:

我可以在 Code Igniter 中做到这一点:

$this->db->select();
$this->from->('node');
if ($published == true)
{
    $this->db->where('published', 'true');
}
if (isset($year))
{
    $this->db->where('year >', $year);
}
$this->db->get();

如何翻译这段代码以便在 Laravel 中工作?

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    在 Laravel > 5.2 中你可以使用when():

    $results = DB::table('orders')
        ->where('branch_id', Auth::user()->branch_id)
        ->when($request->customer_id, function($query) use ($request){
            return $query->where('customer_id', $request->customer_id);
        })
        ->get();
    

    文档:https://laravel.com/api/5.8/Illuminate/Contracts/Container/Container.html#method_when

    博文:https://themsaid.com/laravel-query-conditions-20160425/

    【讨论】:

    • 我在 2020 年 12 月使用了它,它完全符合我的需要。谢谢!
    【解决方案2】:

    我们可以这样写(更精确的方式):

    $query = DB::table('node')->when($published, function ($q, $published) {
            return $q->where('published', 1);
        })->when($year, function($q, $year) {
            return $q->where('year', '>', $year);
        })->get()
    

    在 Laravel 文档中没有提到。这是拉request

    【讨论】:

      【解决方案3】:

      我在这里没见过。您甚至可以像这样开始查询

      $modelQuery = Model::query();

      然后链接其他查询命令。也许这对新人会有帮助。

      【讨论】:

        【解决方案4】:

        您可以在条件中使用Model::when(),也可以创建Builder::micro()

        举例

        $results = Model::where('user_id', Auth::id())
            ->when($request->customer_id, function($query) use ($request){
                return $query->where('customer_id', $request->customer_id);
            })
            ->get();
        

        如果您需要为某个条件创建微,那么。请按照以下说明进行操作。

        在您的服务提供商中编写代码

        Builder::macro('if', function ($condition, $column, $operator, $value) {
            if ($condition) {
                return $this->where($column, $operator, $value);
            }
        
            return $this;
        });
        

        像下面的例子一样使用

        $results = Model::where('user_id', Auth::id())
            ->if($request->customer_id, 'customer_id', '=', $request->customer_id)
            ->get();
        

        参考:themsaid

        【讨论】:

          【解决方案5】:

          对于雄辩的查询,我使用了仅当条件具有值时才执行的后续查询

          ->where(function($query) use ($value_id)
                              {
          
                                      if ( ! is_null($value_id)) 
                                          $query->where('vehicle_details.transport_type_id', $value_id);
          
                              })
          

          【讨论】:

            【解决方案6】:

            截至Laravel 5.2.27,您可以通过这样编写条件来避免破坏链:

            $query = DB::table('node')
                ->when($published, function ($q) use ($published) {
                    return $q->where('published', 1);
                })
                ->when($year, function($q) use ($year) {
                    return $q->where('year', '>', $year);
                })
                ->get();
            

            要使用 Eloquent,只需将 $query = DB::table('node')Node:: 交换,但要意识到如果两个条件都失败,除非您在查询 db/model 或从查询中检查其他条件,否则您将恢复表中的所有内容自己。

            注意$published$year 必须在本地范围内才能被闭包使用。

            您可以通过创建宏使其更加简洁和可读。见:Conditionally adding instructions to Laravel's query builder

            【讨论】:

            • 我并没有真正看到when 的优势。对我来说,一个简单的 if 语句看起来更简洁、更易于阅读并且执行起来可能更快。
            【解决方案7】:

            如果你需要使用 Eloquent,你可以像这样使用它,我不确定 whereNotNull 是最好的用途,但我找不到另一种方法来返回我们真正想要的空查询实例:

            $query = Model::whereNotNull('someColumn');
            if(x < y)   
                {
                    $query->where('column1', 'LIKE', '%'. $a .'%');
                }else{
                    $query->where('column2', 'LIKE', '%'. $b .'%');
                }
            $results = $query->get();
            

            这样任何关系仍然有效,例如在你看来你仍然可以使用

            foreach($results as $result){
                echo $result->someRelationship()->someValue;
            }
            

            http://daylerees.com/codebright/eloquent-queries 上有大量关于这类东西的信息。

            【讨论】:

            • whereRaw(1) 可能是 whereNotNull(fieldname) 的更好选择
            【解决方案8】:

            以下是完成查询的方法:

            $year = 2012;
            $published = true;
            
            DB::table('node')
            ->where(function($query) use ($published, $year)
            {
                if ($published) {
                    $query->where('published', 'true');
                }
            
                if (!empty($year) && is_numeric($year)) {
                    $query->where('year', '>', $year);
                }
            })
            ->get( array('column1','column2') );
            

            要查找更多信息,我建议阅读 Laravel 文档中的 Fluent 和 Eloquent。 http://laravel.com/docs/database/fluent

            【讨论】:

              【解决方案9】:

              在 Fluent 中你可以这样做:

              $query = DB::table('node');
              
              if ($published == true)
                  $query->where('published', '=', 1);
              
              if (isset($year))
                  $query->where('year', '>', $year);
              
              $result = $query->get();
              

              【讨论】:

              • 这只返回一个数组。有没有办法返回一个集合?
              • 这也适用于分页日期,只需将 get 替换为 paginate 或 simplePaginate
              • 我们可以这样写(更精确的方式): $query = DB::table('node')->when($published, function ($q, $published) { return $q ->where('published', 1); })->when($year, function($q, $year) { return $q->where('year', '>', $year); }) ->get()
              • 现在这不是正确的方法。您可以使用 when() 方法。检查文档laravel.com/docs/8.x/queries#conditional-clauses
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-10-05
              • 2018-04-16
              • 2011-09-29
              • 1970-01-01
              相关资源
              最近更新 更多