TP8.0 中用背书枚举重构业务状态码,核心是将字符串比对升级为类型约束,通过 enum OrderStatus: string 实现 IDE 实时校验、数据库与 API 自动映射、前端参数自动解析,并支持扩展业务语义方法。

TP8.0 中用枚举重构业务状态码,不是为了“看起来更高级”,而是让状态判断从字符串比对变成类型约束——一旦写错,IDE 立刻标红,运行时不再因 'shipped' 拼成 'shiped' 而静默出错。
明确区分:纯枚举 vs 背书枚举
业务状态码几乎都得落库、传 API、接前端参数,所以必须用背书枚举(Backed Enum),比如 enum OrderStatus: string。它每个 case 显式绑定一个字符串值,支持双向转换:
-
OrderStatus::Shipped->value→ 得到'shipped',可直接存 MySQLVARCHAR或输出 JSON -
OrderStatus::tryFrom('shipped')→ 返回枚举实例;tryFrom('invalid')→ 返回null,适合处理不可信输入(如 query 参数) -
OrderStatus::from('shipped')→ 成功返回实例,失败抛ValueError,适合内部已校验的数据
替换旧常量,一步到位
把原来散落在模型、服务、控制器里的类常量全部删掉,统一用枚举替代:
- 删掉类似
const STATUS_SHIPPED = 'shipped';的定义 - 在
app/enum/OrderStatus.php中新建枚举:enum OrderStatus: string<br>{<br> case Pending = 'pending';<br> case Shipped = 'shipped';<br> case Cancelled = 'cancelled';<br>} - 控制器方法签名中直接类型约束:
public function update(OrderStatus $status): void—— 框架自动从请求中解析并验证
扩展业务语义,不止于值
枚举可以自带方法,把状态相关的逻辑收拢进来,避免到处写 switch:
- 加中文描述:
public function label(): string { return match($this) { self::Pending => '待处理', self::Shipped => '已发货', self::Cancelled => '已取消' }; } - 加允许的下一个状态:
public function nextStates(): array { return match($this) { self::Pending => [self::Shipped, self::Cancelled], self::Shipped => [], self::Cancelled => [] }; } - 加颜色标识或图标:
public function badgeClass(): string { return match($this) { self::Pending => 'bg-yellow-100', self::Shipped => 'bg-green-100', self::Cancelled => 'bg-red-100' }; }
对接 ThinkORM 与 API 输出
TP8 + ThinkORM 3.0 支持原生枚举映射:
- 模型字段声明为枚举类型:
protected ?OrderStatus $status = null; - 数据库字段设为
VARCHAR(20),ORM 自动调用->value存储,查询时自动用tryFrom()还原 - API 响应中直接
json(['status' => $order->status]),会自动序列化为字符串"shipped",无需手动->value - 前端传参如
?status=shipped,框架自动尝试转成OrderStatus::Shipped,失败则返回 422 错误


















