Laravel 修改数据与原数据一样 导致没有执行sql

代码


$openid = "123"; // 微信openid
User::WhereIn("id",['1','2','3'])->update([
  'openid' => $openid
]);

$user = User::find(1);

// 取消所有这个openid的绑定者
User::Where(['openid' => $openid])->update([
  'openid' => null
]);

// 给1号用户绑定openid
$user->openid = $openid;
$user->save();

问题: openid = 123 有几个?
答案: 一个都没有。

原因

代码极简单

getDirty 会返回 $useroriginal(查询出来的 不允许改变) 和 attributes(手动赋值的) 不同的地方,

最后发现属性都一样,所以 $user->save() 不会执行修改。

扯淡

微信绑定 的时候发现不对劲,还以为是 laravel 或者 mysqlbug :sweat_smile:

当然

本作品采用《CC 协议》,转载必须注明作者和本文链接
专心学习不瞎搞
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 5

看着没有什么问题,这个时候封装的必要性就体现出来了。这个$user变量就不该全局存在

3年前 评论
Adachi 3年前

也就是都是null

3年前 评论
$user = User::find(1);

// 因为此处修改的涉及到 id 为 1的用户,所以$user的变量实际上在数据库已经发生了改变
User::Where(['openid' => $openid])->update([
  'openid' => null
]); 

// 此时$user变量内 open_id为123,而数据表中是null,orm修改时只会对比变量,所以不会修改
$user->openid = $openid;
$user->save();

ORM都是这样的吧,修改的时候逐一对应原数据库的值和变量的值,只修改对比出的差异字段。

要解决的话可以在上面的where条件增加限定 ->where('id', '!=' 1),此处不等于会走索引,倒是问题也不大。

另一种方法可以考虑改变ORM内的原始值

$user = User::find(1);
$user->openid = null;
$user->syncOriginal();
$user->openid = '123';
$user->save();
3年前 评论
lyxxxh (楼主) 3年前
sodasix 3年前

建议在开发环境中使用 Listerer 监听 SQL,这样查找问题会快很多,而且还可以发现查询的时候忘记使用with导致循环查询的问题。

3年前 评论

fillable 中设置 openid 了吗

3年前 评论
杰大哥 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
87
粉丝
105
喜欢
480
收藏
717
排名:109
访问:8.7 万
私信
所有博文
社区赞助商