Laravel变量where子句

时间:2018-11-25 19:57:57

标签: php laravel laravel-5

我正在尝试扩展一个应用程序以使用我的新Laravel应用程序。在这种情况下,我得到的过滤器数量未知,我想将它们全部转发到where()子句。

我做了这样的事情:

private function filterConverter($filter)
{
    $f = [];
    foreach ($filter as $singleFilter) {
        $operator = $this->filterValues[$singleFilter['operator']];
        $value = $operator == 'like' ? '%' . $singleFilter['value'] . '%' : $singleFilter['value'];

        $f[] = $singleFilter['field'] . ',' . $operator . ',' . $value;
    }

    return $f;
}

问题是我得到了EQUALSCONTAINS之类的运算符,因此我需要将它们转换为=LIKE

使用此代码,我正在尝试这样做:

return response(MyModel::where($filter)->get());

但是它不起作用。有解决这个问题的优雅方法吗?

编辑/解决方案

很抱歉@HCK,因为我不能完全接受答案,因为它不能回答我的问题,但这为我指明了正确的方向。解决方案是在数组中使用keyoperatorvalue键,而不要使用我的“无键”键。

private function filterConverter($filters)
{
    $filter = [];
    foreach ($filters as $singleFilter) {
        $operator = $this->filterMap[$singleFilter['operator']];
        $value = $operator == 'LIKE' ? '%' . $singleFilter['value'] . '%' : $singleFilter['value'];

        $filter[] = [
            'key'      => $singleFilter['field'],
            'operator' => $operator,
            'value'    => $value
        ];
    }

    return $filter;
}

2 个答案:

答案 0 :(得分:0)

您可以按照这种方式

DB::table('users')
        ->where(function($query) use ($filter)
        {
            // You able to access $filter here
            // You may able to to generate this block by loop
            $query->where('votes', '>', 100)
                  ->where('title', '<>', 'Admin');
        })
        ->get();

Laravel Doc | Advanced Wheres

Exp-1

    $filters = [
        ['key' => 'votes', 'operator' => '>', 'value' => 100]
    ];

    DB::table('users')
        ->where(function ($query) use ($filters) {
            foreach ($filters as $filter) {
                if (@$filter['key'] && @$filter['operator'] && @$filter['value']) {
                    $query->where($filter['key'], $filter['operator'], $filter['value']);
                }
            }
        })->get();

Exp-2

    $filters = [
        ['key' => 'votes', 'operator' => '>', 'value' => 100]
    ];

    DB::table('users')
        ->where(function ($query) use ($filters) {
            foreach ($filters as $filter) {
                if (@$filter['key'] && @$filter['operator'] && @$filter['value']) {
                    $query->whereRaw("{$filter['key']} {$filter['operator']} '{$filter['value']}'");
                }
            }
        })->get();
  

您还可以使用范围函数Ref

Exp-3 Laravel范围

class User extends Model
{
    public function scopeFilter($query, $filters)
    {
        foreach ($filters as $filter) {
            if (@$filter['key'] && @$filter['value']) {
                $query->where($filter['key'], @$filter['operator']?:"=", $filter['value']);
            }
        }

        return $query;
    }
}

// Use
User::filter($filters)->get();

答案 1 :(得分:0)

不是解决问题的最好方法,但这应该可行:

private function filterConverter($filters)
{
    return collect($filters)->map(function ($filter) {  // <---
        if($filter['operator'] == 'CONTAINS')
        {
            $filter['value'] = '%' . $filter['value'] . '%';
            $filter['operator'] = 'LIKE';
        }
        else if ($filter['operator'] == 'EQUALS')
        {
            $filter['operator'] = '=';
        }

        return collect($filter)->flatten(); // <---
    })->toArray(); // <---
}

在这里,我正在使用Map()类的Collection函数。此类提供了lot of useful methods