You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Eloquent JSON字段筛选问题:用户可查看记录查询失败求助

排查你的Eloquent JSON查询问题

首先得点出你原代码的核心问题:你把JSON数组当成JSON对象来处理啦!allowed和blocked存储的是用户ID数组,但你用allowed->$user_id这种语法是在查找JSON对象里的键,这完全不对路,自然查不出正确结果。

原代码的问题点

  • 对于JSON数组,allowed->$user_id这种写法完全无效,因为数组是值的集合而非键值对结构,Laravel无法识别你要检查数组是否包含某个ID。
  • 虽然allowed为空的判断逻辑是对的,但和错误的数组包含判断组合后,整体查询逻辑直接失效。

正确的实现方式

Laravel专门提供了处理JSON数组的whereJsonContains方法,正好适配你的场景。我们需要调整查询逻辑为:

  1. 满足以下任一条件:
    • allowed字段为空(意味着允许所有用户查看)
    • allowed数组中包含当前user_id
  2. 同时满足:blocked字段为空,或者blocked数组中不包含当前user_id

对应的Eloquent代码如下:

Records::where(function ($query) use ($user_id) {
    $query->whereNull('allowed')
          ->orWhereJsonContains('allowed', $user_id);
})
->where(function ($query) use ($user_id) {
    $query->whereNull('blocked')
          ->orWhereJsonDoesntContain('blocked', $user_id);
})
->get();

补充说明

  • whereJsonContains:检查JSON数组是否包含指定值,Laravel会自动转换为对应数据库的SQL函数(比如MySQL的JSON_CONTAINS)。
  • whereJsonDoesntContain:Laravel 5.7及以上版本支持的方法,用来检查JSON数组不包含指定值。如果你的Laravel版本较低,可以用原生SQL替代这部分逻辑:
    ->whereRaw('NOT JSON_CONTAINS(blocked, ?)', [$user_id])
    
  • 务必把user_id作为参数传入,避免SQL注入风险。

内容的提问来源于stack exchange,提问作者Alex Lomov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:10:50