
本文介绍在 Laravel 中如何正确更新数据库中存储为 JSON 字符串的字段(如 e_service),避免直接对象赋值导致的错误,通过 json_decode、array_replace 和 json_encode 实现精准、安全的局部更新。
本文介绍在 laravel 中如何正确更新数据库中存储为 json 字符串的字段(如 `e_service`),避免直接对象赋值导致的错误,通过 `json_decode`、`array_replace` 和 `json_encode` 实现精准、安全的局部更新。
在 Laravel 应用中,当模型字段(如 e_service)以 JSON 字符串形式存储结构化数据时,不可直接将其当作 PHP 对象进行属性赋值并调用 $model->save()——因为该字段本质是字符串,$booking->e_service 并非可修改的对象,而是 JSON 文本。若强行执行 $booking->e_service->price = ...,将触发 Trying to get property 'price' of non-object 等运行时错误。
正确的做法是:先解析 JSON → 合并更新字段 → 重新序列化 → 写回数据库。推荐使用以下健壮写法:
$booking = Booking::findOrFail($id); // 使用 findOrFail 避免空模型异常
// 安全解码 JSON 字符串为关联数组(第二个参数 true 至关重要)
$eServiceData = json_decode($booking->e_service, true) ?? [];
// 仅覆盖指定键,保留其他原有字段(如 id、mobile_number 等不被意外清空)
$updatedEservice = array_replace($eServiceData, [
'price' => $request->input('price'),
'discount_price' => $request->input('discount_price'),
]);
// 重新编码为 JSON 字符串,并更新数据库
$booking->update([
'e_service' => json_encode($updatedEservice, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
]);
✅ 关键优势说明:
-
array_replace()确保只更新传入的键,原始 JSON 中的id、mobile_number等字段不受影响; -
json_decode(..., true)返回关联数组而非 StdClass 对象,兼容性更好、操作更直观; - 使用
$booking->update()而非$booking->save()可避免触发不必要的模型事件或脏检查逻辑; -
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES提升 JSON 可读性与兼容性(可选但推荐)。
⚠️ 注意事项:
- 始终校验
$request输入(建议配合validated()方法或 Form Request); - 若
e_service字段可能为空或非法 JSON,应添加异常处理(如try/catch或json_last_error()判断); - 长期来看,更规范的方案是将
e_service拆分为独立关系表(如e_services),利用 Eloquent 关联管理,而非在字符串中维护嵌套结构。
通过以上方式,你既能保持现有数据结构兼容性,又能实现安全、可维护的 JSON 字段局部更新。











