You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 14:52:54