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

GRo*_*ing 3 php laravel eloquent laravel-4

我想根据我从json对象收集的搜索参数构造一系列雄辩的WHERE子句.

像这样的东西(不要介意对象的语法,,,它只是演示的解释):

$searchmap = "
{
    "color": "red",
    "height": "1",
    "width": "2",
    "weight": "",
    "size": "",
}";
Run Code Online (Sandbox Code Playgroud)

然后我拿对象并解码得到一个搜索数组......

$search = json_decode($searchmap, true);
Run Code Online (Sandbox Code Playgroud)

如果我的体重和大小设置为null或者是一个"空字符串",我会有一个看起来像这样的雄辩代码.

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

如果他们有一个值,那么雄辩的代码就像这样......

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

有没有办法动态完成这个.

我想这个问题应该是有一种方法可以根据给定的参数动态链接where子句吗?

在伪上下文中,我希望做这样的事情

$gadgets = Gadget::

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

->paginate(9);
Run Code Online (Sandbox Code Playgroud)

可以用类似的方式链接where子句吗?

感谢您抽出宝贵时间来看看这个!


更新:

我也提出了类似的东西似乎运作良好,但我想欢迎建议,如果改进是一个好主意.

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

最后

感谢下面的@lukasgeiter,我想我会选择这个

$gadgets = Gadget::whereNested(function($query) use ($search) {
    foreach ($search as $key => $value)
        {
            if($value != ''){
                $query->where($key, '=', $value);
            }
        }
}, 'and');
$gadgets = $gadgets->paginate(9);
Run Code Online (Sandbox Code Playgroud)

luk*_*ter 7

这很简单.Laravel的where函数允许您传入一组键值对.

$searchmap = array(
    'color' => 'red',
    'height' => '1'
    // etc
);

$gadgets = Gadget::where($searchmap)->paginate(9);
Run Code Online (Sandbox Code Playgroud)

如果你很好奇,那就是源代码的相关部分(\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....
}
Run Code Online (Sandbox Code Playgroud)

编辑

要对它进行更多控制(例如,将"="更改为另一个比较运算符),请尝试直接使用内部代码laravel:

$gadgets = Gadget::whereNested(function($query) use ($searchmap)
        {
            foreach ($searchmap as $key => $value)
            {
                if($value != ''){
                    $query->where($key, '=', $value);
                }
            }
        }, 'and')->paginate(9);
Run Code Online (Sandbox Code Playgroud)