我有一个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']]
);
};
现在明显的问题是,虽然它很容易实现简单的闭包,但传递多个条件是不可能的。 我的问题是,我可以使用什么来准备在闭包内的查询上执行的复杂语句?
答案 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;
}
对象。