发布于2026-07-09 阅读(0)
扫一扫,手机访问
先说说 appendRelationAttr 这个家伙。很多刚接触 ThinkPHP 的朋友,一看到模型关联就头疼,尤其是在做 API 接口返回数据的时候。你明明用 with('profile') 把用户资料查出来了,结果前端同事拿到数据一看,是 {"id":1, "name":"张三", "profile":{"email":"...", "nickname":"..."}} 这种嵌套结构。他们往往更希望直接拿到 {"id":1, "name":"张三", "email":"...", "nickname":"..."} 这种扁平结构,省得再去解析一层。
appendRelationAttr 就是干这个的。它不碰数据库,也不改任何关联逻辑,纯粹是在模型序列化(比如调用 toArray() 或 toJson())的时候,把一对一关联模型的字段“提”到主模型数据的同一层级里去。换句话说,它控制的是输出格式,让 JSON 结构更符合前端预期。
你已经定义好了一对一关联,比如 User 模型关联了 Profile 模型。然后你希望用户在调用 toArray() 时,自动把 profile.email、profile.nickname 这类字段变成 User 对象里的 email、nickname 直接输出——这时候就派上用场了。
with('profile') 预加载。否则,未预加载时 appendRelationAttr 不会自动帮你查,结果字段值要么是 null,要么触发懒加载报错。sa veRel() 或 associate() 的事,别搞混了。一个标准的调用是这样的:
$user = User::with('profile')->find(1);
$data = $user->appendRelationAttr('profile', ['email', 'nickname'])->toArray();
// 输出包含:id, name, email, nickname 等同级字段
'profile' 是关联方法名,必须和模型中定义的函数名完全一致,大小写敏感,别写错了。Profile 模型的属性名(也就是你能读取到的字段名),不是数据库字段名,当然更不是 profile.email 这种点号路径。profile,直接调用 appendRelationAttr 不会主动去查,结果字段就会为 null。所以务必先 with('profile')。hidden/visible 配合时的坑:hidden(['profile.email']) 这种写法是支持的,但 appendRelationAttr 本身不接受点号路径,你传它也不认。有些朋友可能会问:那我直接在模型里定义 protected $append = ['full_name'],再写个 getFullNameAttr() 获取器不也能追加字段吗?没错,但这两者本质不同。
$append 是全局默认行为,每次序列化都会生效,适合计算型字段,比如拼接姓名、格式化时间等。它需要配套一个获取器方法。appendRelationAttr 是运行时单次操作,只影响当前模型实例,而且它直接“映射”关联模型的已有属性,不经过获取器,性能更轻量。hidden 和 visible 会作用于最终合并后的字段列表,包括被 appendRelationAttr 提上来的字段。所以如果你在 visible 里只写了 ['id', 'email'],那 nickname 即使被提上来了也不会显示。如果你用 User::with('profile')->select() 查出来的是一个 Collection(数据集),想批量处理每个模型,那你得逐个模型去调用 appendRelationAttr。因为它是模型实例的方法,不是集合的方法。
$list = User::with('profile')->select();
$result = $list->map(function ($user) {
return $user->appendRelationAttr('profile', ['email', 'nickname'])->toArray();
})->all();
appendRelationAttr,它只属于单个模型实例。profile: { email, nickname } 这种嵌套结构反而更清晰,还能避免字段名冲突(比如主表本来就有个 email 字段?那就尴尬了)。protected $resultSetType = 'collection',appendRelationAttr 依然不具备集合级批量能力,还是得遍历。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8