PHP修改MySQL表中JSON字段内cost值的技术求助
解决方案
错误原因说明
Warning: Attempt to assign property of non-object:十有八九是你把JSON解析成了关联数组,却用对象属性访问的方式($obj->cost)操作;要么就是JSON解析失败,得到了非对象/非数组的无效值。Notice: Array to string conversion:更新数据库时,你直接把修改后的数组/对象存回details字段,没重新编码成JSON字符串,PHP自动把数组转成了字符串(比如直接变成Array),就触发了这个提示。
完整可行代码示例
下面是从数据库读取、修改JSON字段、更新回数据库的完整流程,以PDO为例:
1. 连接数据库
// 替换成你的数据库配置 $dsn = 'mysql:host=localhost;dbname=db;charset=utf8mb4'; $username = '你的用户名'; $password = '你的密码'; try { $pdo = new PDO($dsn, $username, $password, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ]); } catch (PDOException $e) { die('数据库连接失败: ' . $e->getMessage()); }
2. 读取数据并解析JSON
推荐用关联数组解析,避免对象访问的混淆:
// 按实际条件查询数据,这里以id=1为例 $stmt = $pdo->prepare("SELECT id, details FROM objects WHERE id = ?"); $stmt->execute([1]); $row = $stmt->fetch(PDO::FETCH_ASSOC); // 解析JSON为关联数组,第二个参数设为true $details = json_decode($row['details'], true); // 检查解析是否成功 if (!is_array($details)) { die('JSON解析失败,details字段数据无效'); }
如果习惯用对象操作,也可以这么写:
$details = json_decode($row['details']); if (!is_object($details)) { die('JSON解析失败,details字段数据无效'); }
3. 根据type修改cost值
保持和解析方式一致的访问逻辑:
关联数组方式
switch ($details['type']) { case 'small': $details['cost'] = 1; break; case 'big': $details['cost'] = 2; break; default: // 可以保留原cost值,或者加自定义处理 break; }
对象方式
switch ($details->type) { case 'small': $details->cost = 1; break; case 'big': $details->cost = 2; break; default: break; }
4. 重新编码JSON并更新数据库
关键是要把修改后的数组/对象重新转成JSON字符串再存入:
// 重新编码为JSON,JSON_UNESCAPED_UNICODE可选,用于保留中文不转义 $updatedDetails = json_encode($details, JSON_UNESCAPED_UNICODE); // 更新回数据库 $updateStmt = $pdo->prepare("UPDATE objects SET details = ? WHERE id = ?"); $updateStmt->execute([$updatedDetails, $row['id']]); echo '数据更新成功';
额外注意事项
- 确保数据库里
details字段的类型是TEXT、LONGTEXT或者MySQL 5.7+支持的JSON类型,后者更适合存储JSON数据。 - 处理多条数据时,用循环遍历即可,逻辑和单条一致。
- 每次操作前最好验证
details字段的JSON格式是否有效,避免解析失败导致后续错误。
内容的提问来源于stack exchange,提问作者plezhh
相关产品推荐
相关产品推荐

