个人感觉 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();