关于laravel:丰富-Eloquent-ORM-的-where-查询条件的解析场景

33次阅读

共计 3143 个字符,预计需要花费 8 分钟才能阅读完成。

个人感觉 Eloquent ORMwhere 条件解析场景并不是那么的丰盛,很多条件的拼装都须要引入额定的 orWhere, whereNotIn, whereBetween, whereNotBetween 来辅助实现。这样在做一些形象的底层查询方法时,不是很敌对,下层传递的查问条件是不确定的,如果能灵便的解析各种混合式的查问条件(用数组的形式形容),应用起来会更高效灵便些。

/**
 * 渲染简单的 where 查问条件
 * @param Builder $query
 * @param         $conditions
 */
public static function renderWhereMixedEloquent(Builder $query, $conditions)
{$lastEl = end($conditions);
    reset($conditions);
    if (is_string($lastEl) && (('or' == $lastEl || 'and' == $lastEl))) {
        $logic = $lastEl;
        array_pop($conditions);
    } else {$logic = 'and';}
    $conditionsKeys     = array_keys($conditions);
    $conditionsKeyFirst = $conditionsKeys[0];

    if (is_numeric($conditionsKeyFirst)) {if (is_array($conditions[$conditionsKeyFirst])) {if ('or' == $logic) {$query->where(function (Builder $query) use ($conditions) {foreach ($conditions as $conditionsSub) {$query->orWhere(function (Builder $query) use ($conditionsSub) {static::renderWhere($query, $conditionsSub);
                        });
                    }
                });
            } else {$query->where(function (Builder $query) use ($conditions) {foreach ($conditions as $conditionsSub) {$query->where(function (Builder $query) use ($conditionsSub) {static::renderWhere($query, $conditionsSub);
                        });
                    }
                });
            }
        } else {$operator = $conditions[1];
            switch ($operator) {
                case 'in':
                    $query->whereIn($conditions[0], $conditions[2], $logic);
                    break;
                case 'between':
                    $query->whereBetween($conditions[0], $conditions[2], $logic);
                    break;
                case 'not in':
                    $query->whereIn($conditions[0], $conditions[2], $logic, true);
                    break;
                case 'not between':
                    $query->whereBetween($conditions[0], $conditions[2], $logic, true);
                    break;
                default:
                    $query->where(...$conditions);
            }
        }
    } else {$query->where(function (Builder $query) use ($logic, $conditions) {if ('and' == $logic) {foreach ($conditions as $col => $val) {$query->where([$col => $val]);
                }
            } else {foreach ($conditions as $col => $val) {$query->orWhere([$col => $val]);
                }
            }
        });
    }
}

应用示例

简略的 and 条件

$conditions = [
    'name' => 'lily',
    'sex'   => 'f',
];
$conditions = [
    'name' => 'lily',
    'sex'   => ['f', 'm'],
];

简略的 or 条件

$conditions = [
    'name' => 'lily',
    'sex'   => ['f', 'm'],
    'or'
];

简单的 and/or 查问

$conditions = [
    [['id', '>', 5],
        ['hobby', 'in', ['football', 'swimming']],
        ['created_at', 'between', [strtotime('2020-05-20 10:38:41'), strtotime('2021-05-25 10:39:41')]],
    ],
    [['id', '>', 5],
        ['hobby', 'in', ['football', 'swimming']],
        ['created_at', 'between', [strtotime('2020-05-20 10:38:41'), strtotime('2021-05-25 10:39:41')]],
    ],
];// 组 1 and 组 2 
$conditions = [
    [['id', '=', 5],
        ['hobby', 'in', ['football', 'swimming']],
        ['created_at', 'between', [strtotime('2020-05-20 10:38:41'), strtotime('2021-05-25 10:39:41')]],
        'or'// 组 1 的外部做 or
    ],
    [['id', '>', 5],
        ['hobby', 'not in', ['football', 'swimming']],
        ['created_at', 'not between', [strtotime('2020-05-20 10:38:41'), strtotime('2021-05-25 10:39:41')]],
    ],
    'or',// 组 1 or 组 2
];
$conditions = ['sex' => ['f', 'm'],// 没问题,只有表达式的语义正确,只有你头不晕,就能混拼,
    ['name', '=', 'test'],
    [['id', '>', 5],
        ['hobby', 'in', ['football', 'swimming']],
        ['created_at', 'between', [strtotime('2020-05-20 10:38:41'), strtotime('2021-05-25 10:39:41')]],
        'or'// 组 1 的外部做 or
    ],
    [['id', '>', 5],
        ['hobby', 'in', ['football', 'swimming']],
        ['created_at', 'between', [strtotime('2020-05-20 10:38:41'), strtotime('2021-05-25 10:39:41')]],
    ],
    'or',// 组 1 or 组 2
];

应用实例

// < 8.0
$query = User::select("*");// 次要是拿到 Builder 对象
// $query 是对象 援用传值
User::renderWhereMixedEloquent($query, $conditions);
$query->get();

// 8.0
$query = User::query();
// $query 是对象 援用传值
User::renderWhereMixedEloquent($query, $conditions);
$query->get();

正文完
 0