本文详解 laravel eloquent 和 query builder 中安全、兼容地查询 mysql/postgresql 等数据库 json 列(如 `info->id`)的最佳实践,纠正 `whereraw` 拼接导致的 sql 注入与语法错误,并介绍 `wherejsoncontains`、`wherejsonlength` 等高级 json 查询方法。
在 Laravel 中对 JSON 类型字段(如 MySQL 的 JSON 列或 PostgreSQL 的 jsonb)进行条件查询时,切勿直接拼接变量到 whereRaw 中——这不仅存在严重的 SQL 注入风险,还会因引号缺失或类型隐式转换导致报错(例如你遇到的 Unknown column '6112' 错误)。该错误本质是 MySQL 将未加引号的数字 6112 误解析为列名而非字面值,根源在于 ->whereRaw('JSON_EXTRACT(info, "$.id") = '.$value) 缺少参数绑定和字符串转义。
✅ 正确且推荐的方式是使用 Laravel 原生支持的 JSON 路径操作符 ->:
$order = DB::table('orders')
->where('info->id', $value) // ✅ 自动处理类型与转义,等价于 JSON_EXTRACT(info, '$.id')
->first();该语法在 Laravel 5.6+ 中原生支持,底层会根据数据库类型自动编译为对应函数:
同时,它会通过 PDO 参数绑定安全传递 $value,彻底规避注入与语法错误。
? 进阶 JSON 查询场景(仅限 MySQL/PostgreSQL):
匹配 JSON 数组中是否包含某值(如 info->tags 是 ["urgent", "paid"]):
$orders = DB::table('orders')
->whereJsonContains('info->tags', 'urgent')
->get();匹配多个值(AND 逻辑):
// 查找同时包含 'urgent' 和 'paid' 的订单
$orders = DB::table('orders')
->whereJsonContains('info->tags', ['urgent', 'paid'])
->get();按 JSON 数组长度筛选:
// 查找 tags 数组长度大于 1 的订单
$orders = DB::table('orders')
->whereJsonLength('info->tags', '>', 1)
->get();⚠️ 注意事项:

$order = Order::where('info->id', $value)->first();总结:始终优先使用 -> 操作符替代手写 JSON_EXTRACT + whereRaw;它更简洁、安全、跨库兼容,且由 Laravel 框架统一维护底层适配逻辑。