You need to enable JavaScript to run this app. 如何通过点表示法为jsonb字段赋值?Laravel操作报错未生效
优惠活动
大模型
产品
解决方案
定价
更多

如何通过点表示法为jsonb字段赋值?Laravel操作报错未生效

问题现象

开发者尝试通过点表示法为模型关联的jsonb字段设置嵌套键值,执行如下代码:

$user = User::find(123);
Illuminate\Support\Arr::set($user, 'foo.bar', 100);

运行代码后出现两类异常表现:

  • 触发PHP运行时提示:PHP Notice: Indirect modification of overloaded element of User has no effect in /Users/me/my-project/vendor/laravel/framework/src/Illuminate/Collections/Arr.php on line 575
  • 最终输出的数组结构仅包含["bar" => 100],$user模型实例上的foo字段值没有被实际修改,完全不符合预期。
问题根因

Arr::set的设计适用场景是操作原生PHP数组,直接传入Eloquent模型实例会触发两层逻辑错位:

  1. Eloquent模型不管是通过魔术方法__get还是实现的ArrayAccess接口访问属性,拿到的json字段解码后的数组值都是按值传递的副本,和模型内部存储的属性不存在引用关联
  2. Arr::set内部尝试通过数组写入的方式修改这个副本时,因为没有指向模型内部存储的引用链路,根本无法修改到模型实际持有的属性值,自然会触发“重载元素间接修改无效”的PHP提示
  3. 整个修改过程作用在和模型完全隔离的临时变量上,最终形成的零散数组结构也是路径匹配错位的结果。
正确实现步骤
  1. 先从模型上读出对应json字段的现有值,生成独立的可操作数组
  2. 对这个独立数组使用Arr::set通过点表示法设置嵌套键值
  3. 将处理完成的数组赋值回模型的对应字段,触发模型的修改状态标记
    完整示例代码:
$user = User::find(123);
// 取出foo字段的现有值,无值时给默认空数组
$fooData = $user->foo ?? [];
// 对独立数组执行嵌套值设置
Illuminate\Support\Arr::set($fooData, 'bar', 100);
// 将处理后的数组赋值回模型字段
$user->foo = $fooData;
// 保存即可将嵌套值持久化到数据库jsonb字段
$user->save();

前置要求:需要在User模型中给foo字段配置类型转换,即声明protected $casts = ['foo' => 'array'];,否则模型不会自动将赋值的数组序列化为可存储的json字符串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 08:06:10