duancong7358 2014-10-31 12: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 12: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条)
编辑
预览

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部