
laravel 原生 sql 查询中直接使用 `:id` 绑定逗号拼接的字符串会导致参数被整体视为单个值,无法正确匹配 `in` 子句;应改用查询构建器的 `wherein()` 方法,由框架自动处理占位符与参数绑定,确保安全、高效且语义清晰。
在 Laravel 中执行包含 IN 条件的数据库查询时,切勿通过 implode() 拼接 ID 字符串并作为单一绑定参数传入原生 SQL。例如以下写法是错误的:
$id = [6, 7, 8, 9];
$params = [
'connection' => 'redis',
'id' => implode(',', $id) // ❌ 错误:':id' 被绑定为字符串 "6,7,8,9",而非四个独立值
];
$result = DB::select(DB::raw("
SELECT * FROM failed_jobs
WHERE id IN (:id) AND connection = :connection
"), $params);该写法实际生成的 SQL 等效于:
WHERE id IN ('6,7,8,9') -- ⚠️ 仅匹配 id 字段值等于字符串 "6,7,8,9" 的记录(通常无结果)因此只会返回 0 或 1 条(如有 id 恰好为该字符串的异常数据),而非预期的 4 条记录。
✅ 正确做法是使用 Laravel 查询构建器(Query Builder)提供的 whereIn() 方法:
$id = [6, 7, 8, 9];
$result = DB::table('failed_jobs')
->where('connection', 'redis')
->whereIn('id', $id)
->get();此方式优势显著:
- 安全性:自动使用预处理参数绑定,彻底防止 SQL 注入;
- 兼容性:适配所有支持的数据库驱动(MySQL、PostgreSQL、SQLite 等),底层自动展开为 IN (?, ?, ?, ?) 并绑定对应参数;
- 可读性与维护性:语义明确,逻辑直观,无需手动拼接 SQL;
- 类型安全:数组元素会按需转换(如整型保持为整型,避免字符串隐式转换问题)。
⚠️ 注意事项:
- whereIn() 接收的必须是数值索引数组(如 [6,7,8,9]),关联数组将导致意外行为;
- 若数组为空([]),whereIn() 默认返回空集合(Laravel 9+ 默认行为),如需兼容旧版本或特殊逻辑,建议提前校验:if ($id) { ... };
- 如需在原生查询中动态构造 IN 子句(极少数场景),应使用 DB::raw() 配合 str_repeat() 动态生成占位符,并确保参数数组严格对应,但强烈不推荐——这违背了 Laravel 的设计哲学,也增加出错风险。
总结:始终优先选用 Query Builder 提供的高级方法(如 whereIn, whereNotIn, whereBetween),它们不仅更简洁,更能保障应用的安全性与健壮性。










