获取器方法名必须为getFieldNameAttr格式,FieldName是数据库字段转驼峰(如create_time→CreateTime),且需public、至少一个参数$value,第二个参数$data可选;仅在模型读取数据时触发(如->status、toArray()),Db查询不触发;可用withAttr动态覆盖,但须置于查询链最前。

获取器方法名怎么写才生效
必须是 getFieldNameAttr 格式,其中 FieldName 是数据库字段名转驼峰(如 create_time → CreateTime),最终方法名为 getCreateTimeAttr。大小写和 Attr 后缀缺一不可,否则不会触发。
常见错误现象:
-
getCreatetimeAttr(少大写 T)→ 不触发 -
get_create_time_attr(下划线写法)→ 不触发 -
getCreateTime(漏掉Attr)→ 不触发
方法必须是 public,且至少接收一个参数($value),第二个参数 $data 可选(用于访问整行数据)。
什么时候会自动调用获取器
获取器只在模型层读取数据时触发,不是所有取值场景都走它:
立即学习“PHP免费学习笔记(深入)”;
-
$user->status→ 触发 -
$user->toArray()或$user->toJson()→ 触发 -
$user->getAttr('status')→ 触发 -
Db::name('user')->where(...)->find()→ 不触发(这是原生查询,绕过模型) -
$user->getData('status')→ 跳过获取器,返回原始值
注意:如果你在控制器里混用 Db 和 Model,别误以为所有 ->status 都会格式化。
想临时覆盖模型里的获取器怎么办
用 withAttr 方法,在查询链中动态定义,优先级高于模型内定义的同名获取器:
User::withAttr('email', function($value) {
return strtolower($value);
})->withAttr('status', function($value) {
$map = [0 => '停用', 1 => '启用'];
return $map[$value] ?? '未知';
})->select();
但要注意:withAttr 必须放在查询链最前面,且之后不能再调用模型方法(比如 ->where() 无效),只能接 ->select()、->find() 等终态方法;若需加条件,得改用 Db 查询再手动处理。
获取器里怎么拿到其它字段的值
给获取器方法加第二个参数 $data,它就是当前模型实例的全部原始数据数组:
public function getFullNameAttr($value, $data)
{
return $data['first_name'] . ' ' . $data['last_name'];
}
这个技巧常用于拼接字段、状态联动判断(比如根据 type 和 status 共同决定显示文案)。但别在获取器里做 DB 查询或耗时操作——它会在每次取值时执行,容易引发 N+1 问题。
真正容易被忽略的是:获取器不参与数据库写入逻辑,也不影响验证、关联加载或事件钩子;它纯粹是“读时转换”,和修改器完全解耦。用错时机(比如想靠它改入库值)就会白忙活。



















