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

Laravel Query Builder中orWhere查询结果不符的修正方案咨询

修复Laravel查询逻辑错误的解决方案

你的问题出在逻辑运算符的优先级和条件分组上。原查询中,orWhere和后续的where是同级的,而SQL里AND的优先级高于OR,导致实际执行的逻辑是:

(产品名称含关键词) OR (产品标签含关键词 且 状态激活 且 非免费)

这就会把那些名称匹配但状态未激活/免费的产品也查出来,完全不符合你的需求。

正确的做法是把「名称或标签含关键词」这两个条件分组包裹,让它们作为一个整体和其他条件用AND关联。修改后的代码如下:

$products = DB::table('products')
    ->where(function($queryBuilder) use ($query) {
        $queryBuilder->where('products.name', 'like', "%{$query}%")
                     ->orWhere('products.tags', 'like', "%{$query}%");
    })
    ->where('products.status', '=', 1)
    ->where('products.price', '!=', 0)
    ->groupBy('products.id')
    ->latest()
    ->paginate(3);

额外提示(安全优化)

直接拼接%{$query}%虽然能工作,但存在SQL注入风险,同时如果$query里包含%或_这类通配符,会导致匹配结果不符合预期。推荐用参数绑定的方式处理:

$products = DB::table('products')
    ->where(function($queryBuilder) use ($query) {
        $queryBuilder->where('products.name', 'like', DB::raw('concat("%", ?, "%")'), [$query])
                     ->orWhere('products.tags', 'like', DB::raw('concat("%", ?, "%")'), [$query]);
    })
    ->where('products.status', '=', 1)
    ->where('products.price', '!=', 0)
    ->groupBy('products.id')
    ->latest()
    ->paginate(3);

这样既避免了注入风险,也能正确处理含通配符的搜索关键词。

内容的提问来源于stack exchange,提问作者User57

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:24:43