Laravel查询AND与OR混用致deleted=0条件失效问题排查
问题:Laravel Query Builder中
deleted=0条件被忽略的原因及解决方法 这个问题的核心是逻辑运算符优先级和Laravel Query Builder的条件分组逻辑问题,咱们一步步拆解:
问题根源
你原来的Query Builder代码生成的SQL其实是这样的:
SELECT DISTINCT id, name_lv, name_ru, name_en, price, desc FROM product WHERE deleted = 0 AND name_lv LIKE '%search_term%' OR name_ru LIKE '%search_term%' OR name_en LIKE '%search_term%'
SQL中AND的优先级远高于OR,所以实际执行逻辑变成了:(deleted=0 AND name_lv匹配) OR name_ru匹配 OR name_en匹配——这就导致后面两个OR条件完全绕过了deleted=0的限制,这就是删除条件被忽略的原因。
而你最初想要的SQL逻辑是:把三个名称匹配条件用括号包裹,和deleted=0做整体的AND关联,这就需要在Query Builder中用闭包来分组OR条件。
修正后的代码
$products = DB::table('product') ->select('id','name_lv', 'name_ru', 'name_en','price','desc') ->where('deleted', 0) ->where(function($query) use ($request) { // 用闭包包裹OR条件组,生成括号 $query->where('name_lv','LIKE', '%' . $request->q_search . '%') ->orWhere('name_ru','LIKE', '%' . $request->q_search . '%') ->orWhere('name_en','LIKE', '%' . $request->q_search . '%'); }) ->distinct() ->orderBy('price', 'desc') ->paginate(10, ['*'], 'found') ->onEachSide(6);
这段代码生成的SQL完全符合你的预期:
SELECT DISTINCT id, name_lv, name_ru, name_en, price, desc FROM product WHERE deleted = 0 AND (name_lv LIKE '%search_term%' OR name_ru LIKE '%search_term%' OR name_en LIKE '%search_term%')
闭包会告诉Query Builder把内部的条件用括号包裹,确保deleted=0和整个名称匹配组做AND运算,所有筛选结果都必须满足deleted=0的要求。
额外小建议
为了更规范地避免SQL注入风险,推荐用Laravel自动处理的参数绑定写法(其实Laravel会自动处理字符串拼接的LIKE条件,但养成习惯更好):
// 更安全的写法示例 ->where('name_lv', 'LIKE', "%{$request->q_search}%")
内容的提问来源于stack exchange,提问作者Alexey
相关产品推荐
相关产品推荐

