Laravel 中正确绑定多个参数实现 IN 查询的完整指南

Laravel 中正确绑定多个参数实现 IN 查询的完整指南

laravel 中使用原生 sql 的命名占位符(如 `:id`)无法直接绑定数组值,必须改用查询构建器的 `wherein()` 方法或动态生成占位符,否则会导致查询结果不全。

在 Laravel 开发中,当需要根据一组 ID(如 [6, 7, 8, 9])查询数据库记录时,开发者有时会尝试在原生 SQL 中使用命名绑定(DB::select() + :id),但这种方式存在根本性限制:PDO 不支持将数组直接绑定为单个命名参数。你提供的代码:

$id = [6, 7, 8, 9];
$params = [
    'connection' => 'redis',
    'id' => implode(',', $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(若该行恰好 id 字段值为字符串 ‘6,7,8,9’)或完全无匹配,导致结果数量异常。

推荐方案:使用 Query Builder 的 whereIn()(最安全、简洁、可读性强)

$id = [6, 7, 8, 9];

$result = DB::table('failed_jobs')
    ->where('connection', 'redis')
    ->whereIn('id', $id) // ✅ Laravel 自动处理参数绑定与占位符扩展
    ->get();

底层生成的 SQL 类似:

DeepSeek

DeepSeek

幻方量化公司旗下的开源大模型平台

下载

SELECT * FROM `failed_jobs` 
WHERE `connection` = ? AND `id` IN (?, ?, ?, ?)
-- 绑定参数:['redis', 6, 7, 8, 9]

完全避免 SQL 注入风险,并兼容所有数据库驱动。

⚠️ 补充说明:若必须使用原生 SQL(极少数场景)
需手动构造等量占位符,并逐个绑定:

$id = [6, 7, 8, 9];
$placeholders = str_repeat('?,', count($id) - 1) . '?';
$params = array_merge(['redis'], $id);

$result = DB::select(
    "SELECT * FROM failed_jobs WHERE id IN ($placeholders) AND connection = ?",
    $params
);

但此方式易出错、可维护性差,强烈不建议在常规业务中使用

? 总结

  • ❌ :param 命名绑定不支持数组展开;implode() 后绑定是常见误区;
  • ✅ 优先使用 whereIn() —— 它是 Laravel 专为该场景设计的安全抽象;
  • ? 所有参数均经 PDO 预处理绑定,杜绝 SQL 注入;
  • ? 性能无损耗,且支持链式调用、分页、关系预加载等高级特性。

https://www.php.cn/faq/1965465.html

发表回复

Your email address will not be published. Required fields are marked *