应先初始化查询构造器实例再按需追加条件,用filled()判断参数有效性,多orwhere须闭包包裹,复杂表达式用whereraw。

用变量保存查询构造器实例
不要在每个条件分支里重复写完整查询,而是先初始化一个查询对象,再按需追加条件。比如查用户列表时,状态、类型、关键词都可能为空:
- 写法:$query = User::query();
- 之后所有 where() 都调用在 $query 上,返回的仍是该实例,支持链式继续操作
- 最后统一执行 ->latest()->paginate(15),避免重复写分页逻辑
判断参数是否有效再加条件
别用 $request->has(),它对空字符串、0、null 都返回 true,容易误加无效条件。推荐用 $request->filled():
- $request->filled('name'):只在值非空(不是 ''、null、[]、0)时才为 true
- 适合表单搜索字段,天然过滤掉“占位但无意义”的输入
- 例如:if ($request->filled('status')) { $query->where('status', $request->status); }
多个 orWhere 必须用闭包包裹
直接链式写 orWhere 会破坏 AND 优先级,导致本该“同时满足主条件 + 模糊匹配任一字段”的逻辑变成“只要满足任一 or 就行”:
- 错误:$query->where('status', 'active')->orWhere('name', 'like', '%a%')->orWhere('email', 'like', '%a%')
- 正确:$query->where('status', 'active')->where(function ($q) use ($request) { $q->where('name', 'like', "%{$request->q}%")->orWhere('email', 'like', "%{$request->q}%"); })
- 这样生成的 SQL 是 WHERE status = 'active' AND (name LIKE ... OR email LIKE ...),语义准确
需要复杂表达式时用 whereRaw
当标准方法不够用,比如要比较字段运算结果、调用数据库函数,就用 whereRaw:
- 示例:$query->whereRaw('DATEDIFF(NOW(), created_at)
- 占位符 ? 自动绑定参数,防注入
- 也可配合 havingRaw 用于分组后筛选,比如 ->havingRaw('SUM(price) > ?', [1000])











