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

PHP中使用JSON_SET更新嵌套JSON对象的指定键值

解决JSON_SET更新嵌套数组对象时丢失其他属性的问题

问题根源

你之所以会丢失对象的其他属性,是因为错误地用新对象直接替换了整个数组元素(比如把$.b[0]作为路径,赋值{"fin": "新值"}),而不是精准定位到对象内的fin键进行单独更新。

正确解决方案

场景1:按数组索引更新指定对象的fin键

如果知道要更新的对象在b数组中的索引(比如第一个元素,索引为0),直接指定fin键的完整路径即可:

$newFinValue = "新的fin值";
$index = 0; // 要更新的对象在b数组中的索引

$sql = "UPDATE 你的表名 
        SET json字段名 = JSON_SET(json字段名, :path, :newFinValue)";

$stmt = $pdo->prepare($sql);
$stmt->bindValue(':path', "$.b[$index].fin", PDO::PARAM_STR);
$stmt->bindParam(':newFinValue', $newFinValue, PDO::PARAM_STR);
$stmt->execute();

场景2:按对象属性匹配更新(比如按id找目标对象)

如果不知道索引,需要根据对象的某个属性(比如id)匹配目标对象,结合JSON_SEARCH定位路径:

$targetId = 1; // 要匹配的对象id
$newFinValue = "新的fin值";

$sql = "UPDATE 你的表名 
        SET json字段名 = JSON_SET(
            json字段名,
            -- 截取JSON_SEARCH返回的id路径,替换为fin路径
            JSON_UNQUOTE(JSON_SEARCH(json字段名, 'one', :targetId, NULL, '$.b[*].id')) ->> '$[0:-3]' || '.fin',
            :newFinValue
        )
        -- 确保存在匹配的对象
        WHERE JSON_CONTAINS(json字段名, JSON_OBJECT('id', :targetId), '$.b')";

$stmt = $pdo->prepare($sql);
$stmt->bindParam(':targetId', $targetId, PDO::PARAM_INT);
$stmt->bindParam(':newFinValue', $newFinValue, PDO::PARAM_STR);
$stmt->execute();

代码解释:

  1. JSON_SEARCH(json字段名, 'one', :targetId, NULL, '$.b[*].id'):查找b数组中所有id等于targetId的路径,返回格式类似"$.b[0].id"
  2. ->> '$[0:-3]':截取路径字符串,去掉最后的.id,得到$.b[0]
  3. 拼接.fin后,最终路径为$.b[0].fin,JSON_SET只会更新这个键,不会影响对象的其他属性

关键注意点

  • 永远不要直接替换整个数组元素(比如$.b[0]),必须精准到要更新的键的完整路径
  • 确保JSON路径的语法正确,MySQL的JSON路径用$表示根节点,数组索引用[n],对象键用.键名

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 13:27:24