个人感觉 Eloquent ORM
的 where
条件解析场景并不是那么的丰盛,很多条件的拼装都须要引入额定的 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();