Skip to main content

简介

访问器(Accessor)、**修改器(Mutator)和属性类型转换(Cast)**用于在读取或设置 Eloquent 模型属性时对值进行转换。
  • 访问器 — 对从数据库读取的原始值进行加工,再返回给应用
  • 修改器 — 对应用中设置的值进行加工,再保存到数据库
  • 类型转换 — 无需额外方法,通过声明式配置完成属性类型的转换

定义访问器

要定义访问器,需要在模型中添加一个 protected 方法。方法名使用驼峰式,返回类型为 Illuminate\Database\Eloquent\Casts\Attribute。
get 闭包会收到数据库中的原始值。通过模型实例可以以 first_name 属性的形式访问。
如果希望访问器计算得到的值也出现在 JSON/数组中,请把它以蛇形命名的形式加入模型的 $appends 属性。

用多个属性生成值对象

get 闭包的第二个参数是 $attributes(模型的所有属性)。可以组合多列返回一个值对象。

访问器的缓存

返回值对象的访问器,Eloquent 会自动缓存同一实例。如果希望字符串、数字等基本类型也被缓存,可以调用 shouldCache()。
如果要关闭对象缓存,可以使用 withoutObjectCaching()。

定义修改器

修改器通过 Attribute::make() 的 set 参数来定义。可以与访问器写在同一个方法中。
当给模型属性赋值时,set 闭包会被调用。

同时写入多个属性

set 闭包返回数组时,可以一次性更新多个列。

属性类型转换

类型转换允许你在不写访问器和修改器的情况下声明属性的类型转换,是一种简洁的方式。在模型的 casts() 方法中返回一个数组。

内置类型转换一览

null 属性不会被转换。此外,请不要为与关联同名的属性或主键设置类型转换。

Stringable 类型转换

使用 AsStringable 可以让属性以 Illuminate\Support\Stringable 对象的形式使用。

数组 / JSON 转换

可以将 JSON/TEXT 列透明地作为 PHP 数组使用。
也可以使用 -> 运算符只更新 JSON 中的某个键。

AsArrayObject / AsCollection 类型转换

标准的 array 转换在直接修改数组中的某个偏移时会报错。使用 AsArrayObject 或 AsCollection 可以规避此问题。
如果需要使用自定义 Collection 类,可以通过 using() 指定。

向量类型转换

使用 Illuminate\Database\Eloquent\Casts\AsVector 类型转换,可以在数据库的向量列与 PHP 数组之间自动转换。
设置属性时,可以传入 PHP 数组或 Arrayable 实例(例如 Laravel 集合)。获取属性时,该类型转换会返回浮点数数组。

日期时间类型转换

created_at / updated_at 默认会被转换为 Carbon 实例。其他日期时间列也可以用同样方式定义。
指定格式后,JSON 序列化时会使用该格式。
如果要修改所有日期的默认序列化格式,可以重写 serializeDate()(不影响数据库中的存储格式)。
使用 immutable_datetime 时会返回 CarbonImmutable 而不是 Carbon。它可以在不修改原实例的情况下进行日期时间运算,便于写出无副作用的代码。

Enum 类型转换

PHP 8.1 及以上版本的 Backed Enum 也可以作为类型转换。
数据库中存储的是 Enum 的 backing 值(string 或 int),读取时会被转换成 Enum 实例。

Enum 的数组转换

如果需要在一列中以数组的形式保存多个 Enum 值,可以使用 AsEnumCollection。

查询时的类型转换

在执行查询时动态添加类型转换,可以使用 withCasts()。

自定义类型转换

你也可以创建自己的类型转换类。实现 CastsAttributes 接口,并定义 get 与 set 方法。
关于详细的实现方式(Value Object 模式、单向转换、Castables 等),请参考下面的高级页面。

自定义类型转换详解

介绍 CastsAttributes 接口的实现方式,以及 Value Object 模式、Castables 等高级自定义类型转换。

相关页面

Eloquent API 资源

查看如何使用资源类将模型转换为一致的 JSON API 响应。
最后修改于 2026年8月28日