建造复杂的Laravel Eloquent声明使用

时间:2018-04-27 10:19:08

标签: php laravel

我有一个Eloquent\Builder $query我希望使用其他where()来电,其中调用的数量是无限期的,并且来自数组$filter,例如:

$filter = [
    'or:email:=:ivantalanov@tfwno.gf',
    [
        'or:api_token:=:abcdefghijklmnopqrstuvwxyz',
        'and:login:!=:administrator',
    ],
];

字符串在解析时产生有效的SQL条件,但问题在于将它们粘贴到存在组的闭包中(如示例中的字符串2和3 - 数组是他们的' group' )。

我知道Laravel的功能允许将Closure功能粘贴到$query->where()以实现我想要的功能,但我面临的问题实际上是构建那些复杂的闭包。我必须遍历组中的每个字符串并将其传递到生成的闭包中(其中$item是解析条件字符串的结果):

$closure = function ($query) use ($item)
{
    call_user_func_array(
        [$query, $item['function']], [$item['field'], $item['operator'], $item['values']]
    );
};

现在明显的问题是,虽然它很容易实现简单的闭包,但传递多个条件是不可能的。 我的问题是,我可以使用什么来准备在闭包内的查询上执行的复杂语句?

2 个答案:

答案 0 :(得分:0)

我想这会对你有所帮助:

在模型中创建范围:

public static function scopeGetResultList($query) {
     return $query->where(function ($query) use ($item) {
                  $query->where('group_user_holder_type', '=', 1)
                        ->orWhere('group_user_holder_type', '=', 0);
            });
}
  

OR

实施例:     public static function getSearchedUserAuto($ search_key,$ user_id)         {

        $users = DB::table((new User)->getTable().' as U')
                     ->select('U.*', 'CT.city_name', 'C.nicename')
                     ->leftJoin((new Country)->getTable().' as C', 'C.country_id', '=', 'U.user_country')
                     ->leftJoin((new City)->getTable().' as CT', 'CT.city_id', '=', 'U.user_city')
                     ->where(function($query) use ($search_key){
                            $query->where('U.user_full_name', 'like', '%'.$search_key.'%')
                                  ->orWhere('U.user_email', 'like', '%'.$search_key.'%');
                        })
                     ->where(function($query) use ($search_key){
                            $query->where('U.user_full_name', 'like', '%'.$search_key.'%')
                                  ->orWhere('U.user_email', 'like', '%'.$search_key.'%');
                        })
                     ->where('U.status', '=', 1)
                     ->where('U.user_id', '!=', $user_id)
                     ->get();


        return $users;
    }

看看它是否适合你。

答案 1 :(得分:0)

好的,我想我已经明白了。

这是返回最终结果的方法。

<p id="demo"></p>

<script>
  function FPL() {   

    var income = '4200.00';
    var fs = '1';

        var fpl;  
        if(fs == '1') {
            if(income < '1022.00')
               fpl = "0-100%";  
            if (income > '1022.00' && income < '1882.00') 
               fpl = "101-185%";   
            if (result3 > '1882.00' && income < '2033.00') 
               fpl = "186%-200%";
            if (income < '2033.00')
               fpl ="'201% & Over";

            return fpl;                

        }             

        result6 = 'Federal Poverty Level: ' + fpl;

        document.getElementById("demo").innerHTML = result6;
 }   

</script>

这些方法会将初始数组解析为更有用的东西。

public function parse_filter(Builder &$query, array $filter)
{
    $groups = $this->_prepare_groups($filter);
    return $this->_parse_groups($query, $groups);
}

这里是大部分魔法发生的地方。正如您所见,闭包是对此方法的递归调用。

private function _prepare_groups(array $filter)
{
    foreach ($filter as $key => $item) {
        if (is_array($item)) {
            $groups[] = $this->_prepare_groups($item);
        }
        if (is_string($item)) {
            $simple_filter = $this->_parse_simple_filter($item);
            $groups[]      = $simple_filter;
            $simple_filter = null;
        }
    }

    return $groups;
}

private function _parse_simple_filter(string $filter)
{
    $filter_data = explode(':', $filter);

    $simple_filter['function'] = $filter_data[0] === 'and' ? 'where' : 'orWhere';
    $simple_filter['field']    = $filter_data[1];
    $simple_filter['operator'] = $filter_data[2];
    $simple_filter['values']   = $filter_data[3];

    return $simple_filter;
}

使用此方法,您可以使用动态声明的深层嵌套过滤器(例如,在GET / POST请求中接收)修改private function _parse_groups(Builder &$query, array $groups) { foreach ($groups as $operator => $group) { if (!array_key_exists('function', $group)) { $closure = function ($query) use ($group) { $this->_parse_groups($query, $group); }; $query->where($closure); } else { $query->{$group['function']}($group['field'], $group['operator'], $group['values']); } } return $query; } 对象。