where()可传数组或字符串:数组适用于多个等值条件,字符串适用于含操作符的条件;where_in()需判空避免IN()错误;多次where()调用比单次多参数更可靠;LEFT JOIN中时间等条件应写入ON而非WHERE,否则导致LEFT JOIN失效。

where() 传数组还是传字符串?看场景选
传数组适合多个等值条件,比如查 status 是 1 或 2、type 是 'vip' 的记录:
→ $this->db->where(['status' => 1, 'type' => 'vip'])
传字符串适合带操作符的条件,比如日期范围或模糊匹配:
→ $this->db->where('created_at >=', $start)
→ $this->db->where("name LIKE '%{$keyword}%'", NULL, FALSE)(注意第三个参数设为 FALSE 才能绕过自动转义)
where_in() 空数组会出事,必须提前判断
where_in() 遇到空数组([])会生成 IN (),MySQL 直接返回空结果集,不是你想要的“不限制”效果。
常见错误写法:
→ $this->db->where_in('status', $statuses)(没判空)
正确做法:
→ if (!empty($statuses)) { $this->db->where_in('status', $statuses); }
如果业务上允许“全选”,空数组时干脆跳过这行条件,别硬塞 where_in。
多个 where() 调用比单次多参数更可靠
where() 不支持一次传多个字段+值混搭,比如:
→ $this->db->where('id', $id, 'name', $name) —— 后面两个参数会被忽略
真正生效的只有第一个条件。
安全写法是拆成多次调用:
→ $this->db->where('id', $id)->where('name', $name)->where('status !=', 0)
这样逻辑清晰,也方便后续动态增删条件(比如用 if 包裹某一行)。
LEFT JOIN + WHERE 条件容易写错位置
查“未被预订的房间”这类场景,常要关联 booking 表再筛 NULL。
错误写法:
→ $this->db->join('booking b', 'b.room_id = r.id')
→ $this->db->where('b.checkin where('b.checkout >', $start)
这会让 WHERE 把所有没匹配上的房间也过滤掉。
正确做法是把时间条件写进 JOIN ON:
→ $this->db->join('booking b', 'b.room_id = r.id AND b.checkin "' . $start . '"', 'left')
再加 $this->db->where('b.id IS NULL') 才对。
最易被忽略的是:条件写在 ON 还是 WHERE,直接决定 LEFT JOIN 是否失效。一旦漏掉这个细节,查询结果就全偏了。


















