duancong7358 2014-10-31 20:22
浏览 90
已采纳

Laravel - 根据动态参数扩展Eloquent子句

I would like to construct a series of eloquent WHERE clauses dependent on the search parameters I collect from a json object.

Something like this (never mind the syntax of object,,, it is an interpretation only to demonstrate):

$searchmap = "
{
    "color": "red",
    "height": "1",
    "width": "2",
    "weight": "",
    "size": "",
}";

I then take the object and decode to get a search array...

$search = json_decode($searchmap, true);

If my weight and size are set to null or are an 'empty string' I would have eloquent code that looks like this..

$gadgets = Gadget::where('color',   '=', $search['color'])
                 ->where('height',  '=', $search['height'])
                 ->where('width',   '=', $search['width'])
                 ->paginate(9);

If they have a value then eloquent code would look like this..

$gadgets = Gadget::where('color',   '=', $search['color'])
                 ->where('height',  '=', $search['height'])
                 ->where('width',   '=', $search['width'])
                 ->where('weight',  '=', $search['weight'])
                 ->where('size',    '=', $search['size'])
                 ->paginate(9);

Is there a way to accomplish this dynamically.

I suppose the question should be ins there a way to chain eloquent where clauses dynamically based on a given parameter?

In a pseudo context I am looking to do something like this

$gadgets = Gadget::

    foreach ($search as $key => $parameter) {
        if ( $parameter <> '' ) {
            ->where($key, '=', $parameter)
        }
    }

->paginate(9);

Can chaining of where clauses be created in some way similar to this?

Thank you for taking the time to look at this!


UPDATE:

I also came up with something like this that seems to work well but i would like to welcome suggestions if improvement is a good idea.

$gadgets = New Gadget();
    foreach ($search as $key => $parameter) {
        if($parameter != ''){
            $gadgets = $gadgets->where($key, '=', $parameter);
        }
    }
$gadgets = $gadgets->paginate(9);

FINAL

And thanks to @lukasgeiter below I think I will go with this

$gadgets = Gadget::whereNested(function($query) use ($search) {
    foreach ($search as $key => $value)
        {
            if($value != ''){
                $query->where($key, '=', $value);
            }
        }
}, 'and');
$gadgets = $gadgets->paginate(9);
  • 写回答

2条回答 默认 最新

  • dqy27359 2014-10-31 20:28
    关注

    That's easy. Laravel's where function allows you to pass in an array of key value pairs.

    $searchmap = array(
        'color' => 'red',
        'height' => '1'
        // etc
    );
    
    $gadgets = Gadget::where($searchmap)->paginate(9);
    

    If you are curious, that's the relevant part of the source (\Illuminate\Database\Query\Builder)

    public function where($column, $operator = null, $value = null, $boolean = 'and')
    {
        // If the column is an array, we will assume it is an array of key-value pairs
        // and can add them each as a where clause. We will maintain the boolean we
        // received when the method was called and pass it into the nested where.
        if (is_array($column))
        {
            return $this->whereNested(function($query) use ($column)
            {
                foreach ($column as $key => $value)
                {
                    $query->where($key, '=', $value);
                }
            }, $boolean);
        }
    
        // many more lines of code....
    }
    

    Edit

    To have more control over it (e.g. changing the "=" to another comparison operator) try using the code laravel uses internally directly:

    $gadgets = Gadget::whereNested(function($query) use ($searchmap)
            {
                foreach ($searchmap as $key => $value)
                {
                    if($value != ''){
                        $query->where($key, '=', $value);
                    }
                }
            }, 'and')->paginate(9);
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?