Laravel中Like与whereIn组合查询结果不符,需仅返回指定tag_id数据
问题分析
原查询的逻辑错误源于orWhere的优先级问题,导致tag_id的过滤条件仅作用于第二个like条件,最终生成的SQL等价于:
SELECT * FROM users WHERE name LIKE '%search%' OR (description LIKE '%search%' AND tag_id IN (1,3))
这就会出现仅name匹配但tag_id不符合的用户也被返回的情况。
解决方案
需要将两个like条件包裹在同一个where闭包内,让它们形成一个整体的条件组,再与whereIn结合,确保必须同时满足「name/description匹配搜索词」且「tag_id在指定范围内」:
User::where(function($query) { $search = request()->search; $query->where('name', 'like', "%{$search}%") ->orWhere('description', 'like', "%{$search}%"); })->whereIn('tag_id', [1, 3])->get();
这段代码生成的SQL逻辑为:
SELECT * FROM users WHERE (name LIKE '%search%' OR description LIKE '%search%') AND tag_id IN (1,3)
完全符合需求:只有同时满足搜索词匹配且tag_id在[1,3]的用户才会被返回。
额外提示
直接拼接搜索词到like语句存在SQL注入风险,建议使用参数绑定的方式提升安全性:
User::where(function($query) { $search = "%".request()->search."%"; $query->where('name', 'like', $search) ->orWhere('description', 'like', $search); })->whereIn('tag_id', [1, 3])->get();
Laravel会自动对$search进行参数绑定,避免注入风险。
内容的提问来源于stack exchange,提问作者mending3
相关产品推荐
相关产品推荐

