在thinkphp6的教程中,JSON数据更新的例子是这样的
$data['info->nickname'] = 'ThinkPHP';Db::name('user')->json(['info'])->where('id',1)->update($data);
假设json的结构是这样的多层嵌套
{"user": {"bmId": 1245554, "name": "张三", "isUsing": true}, "admin": [], "search_scope": []}
如果写成以下方式,是错误的
$data['u_authority->user->bmId'] = 1245554;Db::name('sys_authority')->json(['info'])->where('id',1)->update($data);
应该以点来分隔路径,而且只能一次更新一个值
$path='user->name';$val='李四';$data['u_authority->'.$path] =$val;Db::name('sys_authority')->json(['u_authority'])->where('id', $id)->update($data);
如果你认为这就没问题了,那就错了,当值为数字的时候,他会转换成字符串存入
$path='user->bmId';$val=123456;$data['u_authority->'.$path] =$val;Db::name('sys_authority')->json(['u_authority'])->where('id', $id)->update($data);
解析成的sql语句与实际写入的不一样,不知道是不是bug
UPDATE `sys_authority` SET `u_authority` = json_set(`u_authority`, '$.user.bmId', 1646226973523) WHERE `id` = 8
最终只能通过exp方式直接写函数解决
public function updateSysAuthority($id,$data){$jsonSet='json_set(`u_authority`';foreach ($data as $key => $value) {if(is_array($value)){switch($value[1]){ case 'int': case 'bool': {$temp=$value[0]?"true":"false";$jsonSet.=",'$." . $key ."',". $temp;break;}case 'array':{$jsonSet.=",'$." . $key ."',JSON_ARRAY(".implode(',',array_map(function($str){if(is_string($str)) return sprintf("'%s'", $str);if(is_bool($str)) return $str?"true":"false";return $str;},$value[0])) .")";break;}case 'str': default:{$jsonSet.=",'$." . $key ."','".addslashes($value[0]) ."'";}}}else$jsonSet.=",'$." . $key ."','".addslashes($value) ."'";}$jsonSet.=')';return Db::name('sys_authority')->where('id',$id)->exp('u_authority', $jsonSet)->update();
}
- 以上方法仅考虑了$data中仅包含3种类型的情况,如果包含多层如array、object时情况会更复杂。
再此向各位大佬寻求能够设定字段类型的方法,以更简单的方式更新多层嵌套字段的某一值。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!