ThinkPHP6模型中状态获取器通过getStatusAttr将数据库数字转为可读文字,如-1→“删除”、0→“禁用”等;可另设getStatusTextAttr提供status_text字段供展示,避免影响原status数值判断;需注意命名规范、空值判断及withAttr动态覆盖等要点。

ThinkPHP6模型中用获取器做状态转换,核心就是把数据库里存的数字(比如0、1、2)自动变成可读文字(如“禁用”“正常”“待审核”),不用每次查完手动switch或if判断。
状态字段获取器怎么写
假设数据表有个status字段,值为整型:-1(删除)、0(禁用)、1(正常)、2(待审核)。在模型里加一个getStatusAttr方法:
- 方法名必须是
get + 字段驼峰名 + Attr,即getStatusAttr(不是get_status_attr或getStatuAttr) - 第一个参数
$value是数据库读出的原始值(比如1) - 第二个参数
$data是整条记录数组,可用于依赖其他字段的逻辑(比如根据is_deleted和status共同决定显示文案) - 记得判空,避免
$value为null时触发 PHP warning
示例代码:
public function getStatusAttr($value, $data = [])
{
if ($value === null) {
return '未知';
}
$map = [-1 => '删除', 0 => '禁用', 1 => '正常', 2 => '待审核'];
return $map[$value] ?? '异常';
}
怎么让状态文本字段独立存在
如果不想覆盖原status字段的行为,而是额外提供一个status_text字段供调用,可以定义getStatusTextAttr:
立即学习“PHP免费学习笔记(深入)”;
- 字段名是
status_text,对应方法名就是getStatusTextAttr - 它不依赖数据库真实字段,纯靠计算生成,所以不会影响
status本身的读写 - 调用时直接写
$user->status_text,框架自动识别并执行该获取器
这样你既能保留原始数值用于条件判断(if ($user->status === 1)),又能方便展示(echo $user->status_text)。
常见踩坑点
状态获取器不生效,大概率是这几个原因:
- 方法命名不对:比如写成
getstatusAttr(首字母没大写)或getStatueAttr(拼错) - 字段名大小写/下划线没转对:数据库字段是
user_status,获取器就得叫getUserStatusAttr,不能漏掉User的U - 没注意
toArray()或toJson()也会触发获取器——如果你希望导出时仍是原始数字,得用$user->getData('status') - 模型里同时配了
$type = ['status' => 'boolean'],导致$value被转成true/false,再拿去查数组就找不到键了
临时覆盖状态显示(比如接口需要掩码)
同一状态字段,在后台要完整显示,在APP接口要脱敏,可以用withAttr动态覆盖:
- 只对链式查询有效,例如:
User::withAttr('status', fn($v) => $v === 1 ? '启用中' : '已停用')->find(5) - 它优先级高于模型里定义的
getStatusAttr,但不影响其他地方的默认行为 - 不能在
find()之后再调withAttr(),那已经晚了



















