访问器用get{attribute}attribute命名,控制读取时格式化;修改器用set{attribute}attribute命名,控制存入前预处理;laravel 10+推荐用attribute类统一管理,逻辑更集中且toarray()默认包含。

直接在模型类里加方法就行,不用额外注册或配置。访问器控制读取时怎么显示,修改器控制存入前怎么处理——两者独立运行,互不影响。
访问器:读取时自动格式化
用 get{Attribute}Attribute 命名,比如数据库字段叫 status,就写 getStatusAttribute。方法接收原始值,返回处理后的结果。
- 定义后,每次访问
$user->status都会自动调用它 - 适合做日期转中文、布尔值转“启用/禁用”、拼接字段(如
first_name + last_name) - 如果想让这个计算字段也出现在
toArray()或 JSON 响应里,得手动加到$appends数组中
修改器:赋值时自动预处理
用 set{Attribute}Attribute 命名,比如字段是 email,就写 setEmailAttribute。方法里必须把处理后的值赋给 $this->attributes['email']。
- 只在模型属性被设置时触发,比如
$user->email = 'ABC@EX.COM'或$user->fill(['email' => '...']) - 对
DB::table()->update()这类原生查询完全无效 - 常见用途:密码加密、邮箱转小写、字符串 trim 和标准化
新写法:用 Attribute 类统一管理(Laravel 10+ 推荐)
在模型里定义一个返回 Attribute 实例的方法,同时支持 get 和 set:
- 语法更简洁,逻辑集中,适合需要双向处理的字段(比如邮箱既要存小写,又要读小写)
- 示例:
public function email(): Attribute { return Attribute::make(get: fn($v) => strtolower($v), set: fn($v) => strtolower(trim($v))); } - 这种写法下,
toArray()默认包含该字段,无需额外$appends
注意事项和避坑点
别把访问器和修改器混用,也别指望它们能替代数据库操作。
- 日期字段优先用
$casts(如'created_at' => 'datetime'),别硬写修改器去转 Carbon,容易绕过时区逻辑 - 修改器不改变查询条件行为——
where('email', 'ABC@EX.COM')还是查原始数据库值,不是小写后的 - 批量赋值(
create()/fill())时,只有键名能匹配模型属性才会触发对应修改器











