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

更新MySQL JSON字段时double值被加双引号如何解决?

问题根因

该问题和PHP侧传入的值类型无关,是illuminate/database本身的逻辑缺陷:组件在处理JSON字段的->快捷更新语法时,会将浮点(double)类型值默认按字符串类型做PDO参数绑定,最终MySQL接收到字符串输入,写入JSON列时就会自动添加双引号存为字符串;整数类型因为组件内部做了特殊类型适配,所以不会出现该问题。

可用修复方案
  • 方案1:用原始表达式包裹浮点值,绕过框架的自动类型转换
    直接给浮点值套一层DB::raw(),让框架把值原样传给MySQL,不做字符串类型绑定,写法最简洁:

    use Illuminate\Support\Facades\DB;
    
    $this->table('table')
        ->where('id', $id)
        ->update([
            'data->test' => DB::raw(34.55),
            'data->test2' => DB::raw(44.99),
        ]);
    

    如果传入的是动态变量,务必先做浮点类型强转再传入DB::raw(),避免SQL注入风险。

  • 方案2:手动调用JSON_SET函数写入
    显式写原生JSON更新逻辑,完全控制传入值的类型:

    use Illuminate\Support\Facades\DB;
    
    $this->table('table')
        ->where('id', $id)
        ->update([
            'data' => DB::raw(sprintf(
                "JSON_SET(data, '$.test', %F, '$.test2', %F)",
                34.55,
                44.99
            ))
        ]);
    

    sprintf的%F占位符会自动把传入值格式化为浮点型字符串,安全拼接进SQL语句,避免注入问题。

  • 方案3:读取全量JSON字段修改后整体回写
    先查询出记录的data字段原值,在PHP侧修改对应键值(保持double类型),再整体编码为JSON回写,框架对整个JSON列的写入会做正确的类型处理:

    $record = $this->table('table')->where('id', $id)->first();
    $data = json_decode($record->data, true);
    $data['test'] = 34.55;
    $data['test2'] = 44.99;
    $this->table('table')
        ->where('id', $id)
        ->update([
            'data' => json_encode($data)
        ]);
    

    该方案会额外产生一次查询开销,适合低并发场景使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:09:26