set{attribute}attribute 方法需手动赋值到 $this->attributes 才生效,仅对 eloquent 的 create/update/save 有效,命名须严格遵循驼峰规则,laravel 10+ 推荐使用 attribute::make() 替代。

直接用 set{Attribute}Attribute 方法就能在保存前处理数据,但必须手动赋值到 $this->attributes,否则不会写入数据库。
set{Attribute}Attribute 方法怎么写才生效
修改器不是“拦截并改写 SQL”,而是模型属性被赋值时触发的钩子。它只对 Eloquent 模型的 create()、update()、save() 有效,对 DB::table()->update() 或原生查询完全无效。
- 方法名必须严格遵循
set{AttributeName}Attribute格式,比如字段是email,就得叫setEmailAttribute - 参数
$value是你传进来的原始值(如$user->email = ' A@B.COM ') - 你必须显式写
$this->attributes['email'] = ...,Eloquent 不会自动帮你存 - 如果字段名含下划线(如
first_name),方法名仍按驼峰写:setFirstNameAttribute
常见错误:密码没加密、空格没 trim、时间没转时间戳
这些看似简单的清洗逻辑,一漏就导致脏数据入库或验证失败。
- 密码哈希:别只写
Hash::make($value),忘了赋值 —— 正确写法是$this->attributes['password'] = Hash::make($value) - 邮箱标准化:用
trim(strtolower($value))处理前后空格和大小写,再存进$this->attributes['email'] - 日期字段:若数据库是
DATETIME类型,传入'2025-10-01'时需转为时间戳或 Carbon 实例,否则可能存成'0000-00-00 00:00:00' - 布尔字段:
setIsActiveAttribute($value)中别直接存(int) $value,Laravel 的$casts已能处理,重复写反而绕过类型转换
Laravel 10+ 推荐用 Attribute::make() 替代传统方法
新语法更清晰、支持类型提示、get/set 可共用逻辑,且避免手写 $this->attributes 出错。
- 定义方式:
public function email(): Attribute,返回Attribute::make(set: fn($v) => trim(strtolower($v))) - 它自动把处理后的值塞进对应字段,不用手动操作
$this->attributes - 如果同时需要 get 和 set,比如金额从“分”转“元”,可一起写:
get: fn($v) => $v / 100, set: fn($v) => (int) round($v * 100) - 注意:旧版写法仍可用,但新项目建议统一用
Attribute,尤其涉及复杂转换时更易读、易测
最容易被忽略的是修改器不参与批量更新(update(['email' => 'x']) 会走,但 where(...)->update(...) 完全不触发),也从不校验数据合法性——它只负责“转换”,不负责“判断该不该存”。真正要拦住非法值,得靠验证器或模型事件。











