getCreateTimeAttr等获取器必须定义在模型类中且仅对模型实例生效,Db查询不触发;命名须严格驼峰(如create_time→getCreateTimeAttr),错一个字符即失效;参数为$value和$data,必须return;可用getData()绕过获取器;withAttr()仅当前查询有效且需立即终结。

getCreateTimeAttr 这类方法必须定义在模型类中,且仅在通过模型实例取值时生效;直接用 Db 查询不会触发。
获取器命名必须严格遵循驼峰规则
数据库字段是 create_time,模型里就得写成 getCreateTimeAttr,不能写成 getCreate_timeAttr 或 getCreatetimeAttr。大小写、下划线位置错一个字符,就完全不触发。
常见错误现象:
-
$user->create_time返回原始时间戳,没格式化 → 检查方法名是否漏了Time中的T -
$user->toArray()里字段仍是数字 → 方法名拼错或没加Attr后缀
获取器参数和返回值要匹配使用场景
方法签名固定为 public function getFieldNameAttr($value, $data = []),其中:
-
$value是数据库读出的原始值(如0、1598765432) -
$data是当前模型的全部原始数据(可用于关联判断,比如根据type字段决定如何处理content) - 必须有
return,否则返回null
示例:状态映射带兜底
立即学习“PHP免费学习笔记(深入)”;
public function getStatusAttr($value)
{
$map = [0 => '禁用', 1 => '启用', 2 => '审核中'];
return $map[$value] ?? '未知';
}
想绕过获取器拿原始值?用 getData() 或 getData('field')
有时候前端需要原始状态码做逻辑判断,但页面又要显示中文,这时不能让获取器干扰业务流。
-
$user->status→ 走获取器,返回“启用” -
$user->getData('status')→ 绕过获取器,返回1 -
$user->getData()→ 返回全部原始字段数组,不含任何加工
注意:getData() 不会触发其他获取器,是纯粹的原始数据快照。
动态获取器 withAttr() 只对当前查询有效,且不能链式接模型方法
临时覆盖某个字段的处理逻辑,比如导出 Excel 时把用户名全转小写,但日常页面展示仍保持原样:
User::withAttr('name', function($value) {
return strtolower($value);
})->select();
关键限制:
- 调用
withAttr()后不能再写->where()->order()等模型方法,否则报错 - 必须立刻接
select()、find()等终结方法 - 若模型中已定义
getNameAttr,此处动态定义会优先生效
Db::name('user')->select(),哪怕结果结构一模一样,所有获取器都彻底失效。这不是 bug,是设计使然——它只属于模型的数据封装层。



















