资讯专栏INFORMATION COLUMN

Laravel 框架 Model 对象转 json 字符串丢失更新

paraller / 635人阅读

摘要:虽然在使用过程中应该小心避免和撞上同名属性,但偶尔还是会碰到的,这个还是稍微注意下就好,这并非,而是在当前的程序处理方式下必然会产生的一个正常现象。

场景还原 UserModel
class UserModel extends Model {
    public function role()
    {
        return $this->belognsTo(RoleModel::class , "role_id" , "id");
    }
}
出错的程序
$user = UserModel::with("role")->find(1);
// $user->role 是一个 RoleModel
// 更新 role 属性
$user->role = "test";
// 正确输出 test
var_dump($user->role);
// 但是!!转换成 json 字符串后
// 你会发现,role 居然还是个模型!!
// 并不是你后面设置成的 test !
// 怪胎,丢失更新了?Laravel Bug ??
// 实际上不是!请看下属描述
var_dump(json_encode($user));
原理概述

LaravelIlluminateDatabaseEloquentModel 实现了 JsonSerializable 接口,所以在调用 json_encode 进行序列化时,会调用 Model::jsonSerialize 方法,他这个方法返回的数据是:

array_merge($attribute , $relation);

实际上你通过:

$model->name = "grayVTouch";

这种方式附加的新属性,Laravel 通过 __set 魔术方法重载,将其添加到 attribute 数组中,你是无法更改 relation 数组的!

而通过 模型关联 你却可以为 relation 数组新增单元!

看到上面的数组合并方式,可以知道 relation 会覆盖掉 attribute 中的同名属性!!因而要特别注意:如果 relation 中有和 attribute 中同名的属性,请修改 relation 关联名称!如果不想修改 relation 名称,坚持前者覆盖后者,请:

// 保存值
$attr = $model->attr;
// 删除属性:attribute / relation 中的属性(Laravel 内部调用 __unset 魔术方法)
unset($model->attr)
// 重新设置值,仅设置到 attribute 数组
// relation 并不会被设置
$model->attr = $model;
综合评价

Laravel 由于将模型属性拆分成两个数组,而他们实际上又同属于一个对象!所以如果存在同名属性,必然会产生 谁覆盖谁 的问题,attribute 一开始就是对应数据库表中的字段的,而 relation 是后面程序附加的,为了不丢失更新,后者覆盖前者,非常正确。

虽然在使用过程中应该小心避免 relationattribute 撞上同名属性,但偶尔还是会碰到的~,这个还是稍微注意下就好,这并非 Bug,而是在当前的程序处理方式下必然会产生的一个正常现象。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/31147.html

相关文章

  • 使用 Laravel 框架开发是什么样的体验

    摘要:但也因为应有尽有使得框架的性能比其他高性能框架低了些,为此给了几个解决方案路由缓存经有关部门研究,路由缓存可有效加快访问速度以上。有朋友说框架最重要的东西是路由,我倒认为最重要的是框架中异于其他框架且能解决痛点的东西,如的。 showImg(https://segmentfault.com/img/remote/1460000006767764); 在程序界的远古时期,大神们手持键盘敲...

    Miracle_lihb 评论0 收藏0
  • [译] 使用 PHPStorm 开发 Laravel 应用

    摘要:很多程序员使用创建他们的应用程序。是一个免费开源的应用程序框架。是的模板语言,对艺术家友好,这个程序员的命令行工具可以在中工作使用插件和帮助器我们可以进一步扩展对应用的支持。 很多PHP程序员使用 [laravel] 创建他们的应用程序。[laravel] 是一个免费开源的PHP web应用程序框架。它基于多个Symfony 组件,提供了一个开发框架,包括authentication,...

    buildupchao 评论0 收藏0
  • 基于Model Event模型事件的Laravel实时APP

    摘要:重点是在页面写入新文本,页面不能实时显示。想要了解更多可以参考这篇文章基于驱动的事件广播下测试实时功能刷新页面,并观察数据库。测试实时创建功能。 说明:本文主要来源于real-time-apps-laravel-5-1-event-broadcasting 本文主要基于Laravel的Model Event介绍该框架的实时通信功能,Laravel模型的生命周期中包含事件:created...

    afishhhhh 评论0 收藏0
  • PHP_Laravel

    摘要:简介是一套简介,优雅开发框架,通过简单,高雅,表达式语法开发应用。服务器需要有该目录及所有子目录的写入权限可用于存储应用程序所需的一些文件该目录下包括缓存和编译后的视图文件日志目录测试目录该目录下包含源代码和第三方依赖包环境配置文件。 简介 Laravel是一套简介,优雅PHP Web开发框架(PHP Web Framework), 通过简单,高雅,表达式语法开发Web应用。 特点: ...

    NoraXie 评论0 收藏0
  • laravel入门

    摘要:开发根目录测试分为单元测试和功能测试创建一个文件执行测试测试前清除配置缓存运行单个测试用例小提示在开发与进行交互的第三方扩展包时,最好选择注入契约而不使用。 参考https://laravelacademy.org/ 概念 单词 契约Contract 就是接口 repository 仓库(封装数据访问,可以搜索:repository模式) Container 容器 ServicePr...

    韩冰 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<