如何在 Laravel 中正确更新数据库 JSON 字段的嵌套对象值

胖丽酱_4470

胖丽酱_4470

2026-06-30

162人浏览

原创

如何在 Laravel 中正确更新数据库 JSON 字段的嵌套对象值

在 Laravel 中直接通过 column->path 语法更新 JSON 字段的嵌套对象时,若传入已编码的 JSON 字符串会导致双重转义;正确做法是逐字段指定路径更新,或使用原生 SQL/JSON 函数实现原子性批量更新。

在 laravel 中直接通过 `column->path` 语法更新 json 字段的嵌套对象时,若传入已编码的 json 字符串会导致双重转义;正确做法是逐字段指定路径更新,或使用原生 sql/json 函数实现原子性批量更新。

在 Laravel 中操作数据库 JSON 字段(如 MySQL 的 JSON 类型或 PostgreSQL 的 jsonb)时,常遇到一个典型陷阱:试图用 json_encode() 后的字符串直接赋值给 column->key 路径,结果导致 JSON 值被意外转义为字符串。例如:

// ❌ 错误:导致 {"data": "{\"total\":22,\"time\":5}"}
$json_data = json_encode(['total' => 22, 'time' => 5]);
DB::table('items')->where('id', 1)->update(['meta->data' => $json_data]);

这是因为 Laravel 的 -> 路径语法底层仍依赖 SQL 的 JSON 路径表达式(如 MySQL 的 JSON_SET 或 JSON_REPLACE),而直接赋值字符串会被当作纯文本写入,而非解析为 JSON 对象。

✅ 推荐解决方案如下:

方案一:逐字段更新(兼容性最佳,适用于所有 Laravel 版本 + MySQL/PostgreSQL)

显式拆解目标数组,为每个嵌套键指定完整 JSON 路径:

js2java
js2java

JavaScript 到 Java 全栈翻译助手,专为前端开发者学习 Java 或快速实现后端业务逻辑而设计。当用户提到以下场景时必须使用此技能: - "帮我把这段 JS 代码转成 Java" - "用 Java 怎么写这个逻辑" - "我习惯用 JS 写,想翻译成 Java" - "教我 Java,我要写后端接...

下载
$data = ['total' => 22, 'time' => 5];

DB::table('items')
    ->where('id', 1)
    ->update([
        'meta->data->total' => $data['total'],
        'meta->data->time'  => $data['time'],
    ]);

✅ 优势:无需额外依赖,语义清晰,避免序列化干扰;
⚠️ 注意:仅更新指定字段,其余 data 下的属性(如 data->user_id)保持不变。

方案二:使用原生 JSON 函数(MySQL 5.7+ / PostgreSQL,原子性强)

利用数据库原生能力一次性合并/替换整个子对象,避免多次查询与竞态:

// ✅ MySQL 示例:使用 JSON_SET 替换整个 "data" 对象
DB::statement(
    "UPDATE items SET meta = JSON_SET(meta, '$.data', ?) WHERE id = ?",
    [json_encode(['total' => 22, 'time' => 5]), 1]
);

// ✅ PostgreSQL 示例(jsonb):使用 jsonb_set
DB::statement(
    "UPDATE items SET meta = jsonb_set(meta, '{data}', ?::jsonb) WHERE id = ?",
    [json_encode(['total' => 22, 'time' => 5]), 1]
);

? 提示:Laravel 10+ 在 Illuminate/Database/Query/Builder 中已内置对 JSON_SET 等函数的部分支持,但跨平台一致性仍建议封装为 DB::raw() 或使用包(如 staudenmeir/laravel-json-relations)。

方案三:读-改-写(通用但需事务保护)

若结构复杂或需条件逻辑,可先取回、修改再写入,务必包裹事务防止并发覆盖:

DB::transaction(function () use ($data) {
    $item = DB::table('items')->where('id', 1)->first();
    $current = json_decode($item->meta, true) ?: [];

    // 深度合并或覆盖 data 子对象
    $current['data'] = array_merge($current['data'] ?? [], $data);

    DB::table('items')->where('id', 1)->update([
        'meta' => json_encode($current, JSON_UNESCAPED_UNICODE)
    ]);
});

总结与最佳实践

  • ❌ 避免对 column->path 直接赋值 json_encode() 字符串;
  • ✅ 优先使用逐字段路径更新(方案一),简洁安全;
  • ✅ 高并发或需原子性时,选用原生 JSON 函数(方案二),性能更优;
  • ⚠️ 使用读-改-写(方案三)时,必须加事务,并考虑乐观锁或版本字段;
  • ? 所有 JSON 操作前建议校验字段类型(如 JSON_VALID(meta))及路径存在性,提升健壮性。

通过合理选择更新策略,即可精准、高效、安全地维护 JSON 字段中的嵌套结构。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2023.09.01

10484

6

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

6161

5

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

2115

5

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

2023.10.23

3888

4

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

2023.10.23

4594

6

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.03

3591

9

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.09

5137

8

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.13

4022

8

sprintf函数用法详解
sprintf函数用法详解

sprintf函数的用法:1、格式化字符串;2、指定输出宽度和精度;3、返回值。更多关于sprintf函数用法详解的内容,大家可以阅读下面的文章。

2023.11.27

12002

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
如何安装 Composer
如何安装 Composer

共1课时 | 206人学习

Composer手册
Composer手册

共0课时 | 0人学习