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

时间: 2019-01-29阅读: 1039标签: Laravel

场景还原

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));


原理概述

Laravel 的 Illuminate\Database\Eloquent\Model 实现了 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 是后面程序附加的,为了不丢失更新,后者覆盖前者,非常正确。 虽然在使用过程中应该小心避免 relation 和 attribute 撞上同名属性,但偶尔还是会碰到的~,这个还是稍微注意下就好,这并非 Bug,而是在当前的程序处理方式下必然会产生的一个正常现象。

站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/2639

关闭

Laravel框架从九个方面提高Web应用的开发效率和竞争优势

由Taylor Otwell于2011年开发的Laravel PHP框架,是软件开发领域的一项创新。它凭借着敏捷的开发方式,在众多PHP框架中脱颖而出。通过它所提供的各项优势和强大的功能

Laravel中9个不经常用的小技巧

更新父表的timestamps:如果你想在更新关联表的同时,更新父表的timestamps,你只需要在关联表的model中添加touches属性。

Composer,laravel下载和更新

有两种方式启用本镜像服务:系统全局配置: 即将配置信息添加到 Composer 的全局配置文件 config.json 中。单个项目配置: 将配置信息添加到某个项目的composer.json 文件中。

Laravel中集成PayPal

最近在写一个面向国外买家的一个商城项目,既然面向国外,那就要用到PayPal这个支付平台。因为在对接PayPal的过程中遇到了一些问题,花费了一些时间,所以把对接的过程记下来,也希望能帮助到用到PayPal的朋友。我集成的是paypal/rest-api-sdk-php。

Laravel 如何优雅地实现输出结构统一的功能?

一般的项目需求都会要求统一的输出结构,特别是对于api应用而言。因此,如果有beforeResponse的功能,则可以在数据输出之前对response进行统一格式化处理。假设这么一种场景

Laravel 向公共模板赋值

开发过程中许多时候都会向公共模板赋值,比如顶部导航栏,页面底部等等,不可能在每个控制器中都赋值一遍。Laravel 中解决办法如下:

十个推荐使用的 Laravel 的辅助函数

Laravel 包含各种全局辅助函数。 laravel 中包含大量辅助函数,您可以使用它们来简化开发工作流程。 在这里,我将编写10个最好的 laravel 帮助函数,用于使我的开发更容易。 您必须考虑在必要时使用它们。

分享 8 个 Laravel 模型时间戳使用技巧

默认情况下,Laravel Eloquent 模型默认数据表有 created_at 和 updated_at 两个字段。当然,我们可以做很多自定义配置,实现很多有趣的功能。下面举例说明。

分享 10 个你可能不知道的 Laravel Eloquent 小技巧

Laravel 是一个功能丰富的框架。但是,你无法从官方文档中找到所有可用的功能。以下是一些你可能不知道的功能。获取原始属性:当修改一条 Eloquent 模型记录的时候你可以通过调用

关于Laravel 与 Nginx 限流策略防止恶意请求

最近公司最近的几台线上服务器经常出现CPU覆盖过高,影响部分应用响应超时,产生了大量的短信和邮件报警,经过排查数据库日志和access.log,发现是API接口被刷,被恶意疯狂请求,最大一次大概120次/s。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!

文章投稿关于web前端网站点搜索站长推荐网站地图站长QQ:522607023

小程序专栏: 土味情话心理测试脑筋急转弯幽默笑话段子句子语录成语大全运营推广