Eloquentupdate方法详解与使用教程
本文深入解析了Laravel Eloquent模型中`update()`方法的内部机制,揭示了其在更新指定字段的同时,会一并持久化模型实例上所有“脏”属性的特性。这是因为`update()`方法内部实际调用了`save()`方法。为了避免意外更新,文章推荐使用查询构建器直接进行更新,并详细阐述了更新后同步模型实例状态的重要性。通过实例演示和源码分析,本文旨在帮助开发者全面理解`Eloquent update()`的行为,掌握更精确的数据持久化控制技巧,从而编写出更健壮、可预测的Laravel应用,提升SEO优化效果。关键词:Eloquent update, Laravel, 模型更新, 脏属性, 查询构建器, 数据持久化, SEO优化。

Eloquent update() 方法的内部机制
在使用Eloquent时,开发者通常会通过模型实例调用update()方法来更新数据库记录。然而,一个常见的误解是,update()方法只会更新作为参数传入的特定字段。实际上,当您通过模型实例调用update()方法时,Eloquent的内部实现会首先填充(fill)传入的属性,然后调用模型的save()方法。
查看Eloquent Model.php 的源码,update()方法的定义清晰地揭示了这一点:
/**
* Update the model in the database.
*
* @param array $attributes
* @param array $options
* @return bool
*/
public function update(array $attributes = [], array $options = [])
{
if (! $this->exists) {
return false;
}
return $this->fill($attributes)->save($options);
}这意味着,update()方法本质上是fill()和save()方法的组合。而save()方法的作用是持久化模型实例上所有已修改(即“脏”)的属性到数据库。因此,如果在调用update()之前,模型实例上已经有其他属性被修改,这些“脏”属性也会随着update()操作一并被保存。
示例:
考虑以下代码片段:
$user = User::find(1); // 从数据库加载用户 $user->is_admin = 1; // 将is_admin属性标记为“脏” $user->update(['first_name' => 'Alex']); // 更新first_name // 此时,数据库中的 is_admin 字段也会被更新为 1
在这个例子中,即使update()方法只指定了更新first_name,但由于在调用update()之前is_admin属性已被修改,update()内部调用的save()方法会将is_admin的更改也一并写入数据库。
避免意外更新“脏”属性的策略
为了避免update()方法意外地持久化模型实例上的所有“脏”属性,当您只想更新特定字段而忽略模型实例上其他已修改的属性时,推荐使用查询构建器(Query Builder)的update()方法。
查询构建器的update()方法直接对数据库执行更新操作,它不涉及Eloquent模型实例的save()生命周期,因此只会更新您明确指定的字段。
解决方案:使用查询构建器进行更新
$user = User::find(1); // 获取模型实例 $user->is_admin = 1; // 此时is_admin属性已被修改,但我们不想保存它 // 使用查询构建器直接更新数据库 User::whereKey($user->getKey())->update(['first_name' => 'Alex']); // 注意:此时 $user 实例的 first_name 属性仍是旧值,is_admin 仍是 1。 // 数据库中的 first_name 已更新为 'Alex',is_admin 保持不变。
通过User::whereKey($user->getKey())->update(['first_name' => 'Alex']);,我们绕过了模型实例的save()方法,确保只有first_name字段被更新。
更新后同步模型实例状态
当您使用查询构建器直接更新数据库时,当前的Eloquent模型实例并不会自动反映这些更改。为了保持模型实例与数据库的同步,您需要手动更新模型实例的属性。
$user = User::find(1);
$user->is_admin = 1;
// 使用查询构建器更新数据库
User::whereKey($user->getKey())->update(['first_name' => 'Alex']);
// 手动同步模型实例的属性
$user->first_name = 'Alex';
// 如果需要将该属性标记为“非脏”并更新原始属性,可以使用 setOriginalAttribute
$user->setOriginalAttribute('first_name', 'Alex');setOriginalAttribute()方法可以将指定属性的“原始值”设置为新值,这有助于在后续操作中正确判断属性是否被修改(即是否为“脏”)。如果只是简单地赋值$user->first_name = 'Alex';,那么$user->isDirty('first_name')将为false,但$user->getOriginal('first_name')仍是旧值。使用setOriginalAttribute可以更彻底地同步。
总结与注意事项
- Model::update()行为: 通过Eloquent模型实例调用update()方法,会触发fill()和save()操作,因此会持久化模型实例上所有已修改的“脏”属性,而不仅仅是传入update()方法的属性。
- 精确控制更新: 当您只想更新数据库中特定字段,而不想影响模型实例上其他已修改但未打算保存的属性时,应使用查询构建器的where()->update()方法。
- 模型实例同步: 使用查询构建器更新数据库后,请务必手动更新或刷新您的Eloquent模型实例,以确保其状态与数据库保持一致。可以使用$model->refresh()(会进行一次新的数据库查询)或手动设置属性并使用setOriginalAttribute()。
- syncOriginal()方法: syncOriginal()方法用于将模型当前属性值同步为原始值,有效地清除所有“脏”状态。它可以在save()或update()操作之前使用,以确保只有在syncOriginal()之后发生的修改才会被持久化。但在上述场景中(即update()方法已经调用save()),syncOriginal()在update()之后调用将无法阻止update()保存脏属性,因为它已经完成了保存操作。其主要用途是在保存操作前重置模型状态,或在获取模型后立即清除其初始的“脏”状态。
理解Eloquent update()方法的底层机制,并根据实际需求选择合适的更新策略,是编写健壮、可预测Laravel应用的关键。
今天带大家了解了的相关知识,希望对你有所帮助;关于文章的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~
ES6生成器实现异步控制技巧
- 上一篇
- ES6生成器实现异步控制技巧
- 下一篇
- Python中len的作用是什么?
-
- 文章 · php教程 | 13小时前 | JSON · api设计 · php教程 · php json_encode JsonSerializable JSON_THROW_ON_ERROR jsonSerialize
- PHP JsonSerializable 控制对象输出字段
- 129浏览 收藏
-
- 文章 · php教程 | 16小时前 | 内存优化 · php教程 · php 文件上传 php://input stream_filter php_user_filter
- PHP stream_filter 处理上传内容的分段方式
- 292浏览 收藏
-
- 文章 · php教程 | 3天前 |
- PHP Lazy Objects 延迟初始化实体的状态边界
- 409浏览 收藏
-
- 文章 · php教程 | 3天前 |
- PHP Attributes 扫描控制器元数据的缓存方法
- 357浏览 收藏
-
- 文章 · php教程 | 3天前 |
- PHP Enum 映射数据库值的类型安全方案
- 278浏览 收藏
-
- 文章 · php教程 | 3天前 | php教程 · php Fiber 事件循环 非阻塞I/O Fiber::suspend Fiber::resume
- PHP Fiber 在阻塞 I/O 封装中的调度边界
- 176浏览 收藏
-
- 文章 · php教程 | 3天前 |
- PHP DateTimeImmutable 按时区转换并保持原对象
- 485浏览 收藏
-
- 文章 · php教程 | 3天前 | PHP · 日期时间 · php 时区 DateTimeImmutable createFromInterface
- PHP DateTimeImmutable createFromInterface 怎么保留时区
- 201浏览 收藏
-
- 文章 · php教程 | 4天前 |
- PHP Closure bindTo 改变作用域时有哪些限制
- 394浏览 收藏
-
- 文章 · php教程 | 4天前 | HTTP · php教程 · php Http请求 file_get_contents stream_context
- PHP stream_context 怎么为单次 HTTP 请求设置选项
- 263浏览 收藏
-
- 文章 · php教程 | 4天前 | PHP ·
- PHP filter_input 为什么读取不到代码中后改的值
- 237浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 293次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 346次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 352次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 315次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 135次使用
-
- PHP JSON_THROW_ON_ERROR 抛错后怎么保留原始字段位置
- 2026-09-09 501浏览
-
- PHP 8.5 array_last() 怎么处理空数组:从 null 结果到兼容旧版本的 Polyfill
- 2026-08-16 501浏览
-
- 宝塔配置Ruby环境:RVM+Nginx反代教程
- 2026-05-29 501浏览
-
- unset函数作用范围详解
- 2026-05-29 501浏览
-
- VS Code配置Xdebug教程:PHP调试技巧全解析
- 2026-05-13 501浏览

