Laravel集合搜索查询报where调用、explode参数错误求助
问题原因
两个报错和逻辑问题的根源如下:
- 报错
Call to a member function where() on Array:PHP原生数组没有where这类集合操作方法,只有将数组转换为Laravel Collection实例后,才能调用集合提供的筛选、排序方法,直接对数组调用成员方法必然触发错误。 - 报错
explode() expects parameter 2 to be string, object given:混淆了Eloquent查询构造器和普通集合的方法规则。普通集合的where方法仅支持键、操作符、值的简单等值判断,不支持传入闭包实现多条件组合查询,传入闭包会触发参数类型不匹配错误。 - 额外逻辑bug:Collection的链式调用不会修改原集合实例,调用筛选方法后没有接收返回值,即使方法写对也拿不到筛选后的结果;最后返回的
$user变量未定义,$count统计的是未筛选的总条数,和实际返回的列表长度不匹配;原SQL直接拼接$mid参数存在SQL注入风险。
修正代码
直接替换原有控制器方法即可:
public function index($mid,$payload){ $search = $payload['search'] ?? ''; // SQL使用参数绑定,避免SQL注入 $users = DB::select('SELECT a.id, a.alternate_id, a.setujuterma, a.mykad, a.nama, a.email, a.notel, a.etunai, b.ranktitle, c.ranktitle AS appointed_rank, d.nama as hirarki, e.alternate_id as placement, e.nama as leadername, a.akses, a.suspendreason, a.regstamp, a.matagajet, f.display as hirarkidisplay, IF(a.mykadverify = "3","1","0") as mykadverifydecode FROM pengguna as a LEFT JOIN penggunarank b ON a.effective_rank = b.id LEFT JOIN penggunarank c ON a.appointed_rank = c.id LEFT JOIN hirarki d ON a.userrank = d.id LEFT JOIN pengguna e ON a.placement = e.id LEFT JOIN hirarkimid f ON a.userrank = f.hirarki AND a.mid = f.mid WHERE a.mid = ? AND a.akses != -1', [$mid] ); // 排序后直接保留集合实例,不需要提前转回数组 $collection = collect($users)->sortByDesc('alternate_id'); // 多字段模糊搜索用filter方法实现 if ($search) { $collection = $collection->filter(function ($item) use ($search) { // 任意字段匹配搜索词即保留该条记录,stripos不区分大小写 return stripos($item->alternate_id, $search) !== false || stripos($item->nama, $search) !== false || stripos($item->mykad, $search) !== false || stripos($item->notel, $search) !== false || stripos($item->email, $search) !== false; }); } // 统计筛选后的实际条数 $count = $collection->count(); // 重置集合键后转回数组 $userList = $collection->values()->toArray(); return [ $userList, $count ]; }
修正说明
- 给
$search增加空值兜底,避免未传search参数时触发未定义索引报错 - 原SQL的字符串拼接改为参数绑定,消除SQL注入风险
- 移除排序后多余的
toArray()调用,全程在集合实例上操作,减少无意义的类型转换 - 用
filter方法替代错误的闭包传where写法,在闭包内通过字符串匹配判断是否符合搜索条件,使用stripos实现不区分大小写的模糊匹配 - 所有集合链式调用的结果都重新赋值给变量,解决筛选操作不生效的问题
- 修正未定义的
$user变量,返回实际处理后的用户列表 - 总条数改为筛选后的集合长度,保证返回的总数和列表条数一致
内容的提问来源于stack exchange,提问作者Ammar Low
相关产品推荐
相关产品推荐

