PHP 8.1 枚举实用笔记:支持纯枚举(无值)与背书枚举(int/string),需用::tryFrom()安全反序列化,::cases()遍历所有项,match($this)封装业务方法,array_column可快速生成下拉选项。

要为 PHP 8.1 枚举类型整理一份实用、可直接复用的笔记,需聚焦真实开发场景中的高频操作:定义、遍历、取值、反序列化、方法封装,且每项都必须能立刻在项目中粘贴运行。
定义纯枚举与背书枚举
纯枚举用于状态标识,不绑定外部值;背书枚举(Backed Enum)必须指定底层类型(int 或 string),否则无法使用 ->value 或 ::from()。
方法一:纯枚举(Unit Enum)
直接声明,无等号赋值:enum OrderStatus { case Draft; case Confirmed; case Shipped; }
方法二:背书枚举(字符串型)
冒号后写 string,每个 case 后必须显式赋字符串值:enum PaymentMethod: string { case Alipay = 'alipay'; case Wechat = 'wechat'; case Bank = 'bank'; }
立即学习“PHP免费学习笔记(深入)”;
方法三:背书枚举(整数型)
冒号后写 int,值必须为整数常量,不能是变量或表达式:enum Priority: int { case Low = 1; case Medium = 2; case High = 3; }
安全获取枚举实例(防崩溃关键)
从 HTTP 请求、数据库读取或 JSON 解析得到的原始值(如 $_GET['status'])绝不可直接调用 ::from(),它会在值不存在时抛出 ValueError 导致脚本中断。
第一步:始终用 ::tryFrom() 替代 ::from():$status = OrderStatus::tryFrom('draft');
第二步:立即判断返回值是否为 null:if ($status === null) { throw new InvalidArgumentException('非法状态值'); }
第三步:确认有效后再使用:echo $status->name; // 输出 Draft
注意:tryFrom() 仅对背书枚举可用;纯枚举只能用 ::fromName() 或 ::tryFromName(),但 PHP 8.1 原生不支持该方法——需自行封装或升级至 PHP 8.3+。
一次性获取所有枚举项名称和值
无需手动维护数组,PHP 8.1+ 原生提供 ::cases() 静态方法,返回按定义顺序排列的枚举实例数组。
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
获取全部名称(适用于纯枚举和背书枚举):$names = array_column(OrderStatus::cases(), 'name');
获取全部背书值(仅背书枚举可用):$values = array_column(PaymentMethod::cases(), 'value');
生成键值对供下拉菜单使用:$options = array_column(PaymentMethod::cases(), 'value', 'name');
结果为 ['Alipay' => 'alipay', 'Wechat' => 'wechat', ...],可直接传给前端 select 组件。
为枚举添加业务方法
把状态相关逻辑收进枚举内部,避免散落在控制器或服务类里。方法内必须用 match($this) 分支处理,这是 PHP 枚举方法的标准写法。
方法一:返回中文标签public function label(): string { return match($this) { self::Draft => '草稿', self::Confirmed => '已确认', self::Shipped => '已发货', }; }
方法二:判断是否为终态(不可逆状态)public function isTerminal(): bool { return match($this) { self::Shipped => true, default => false, }; }
方法三:组合多个逻辑(例如带颜色的状态徽标)public function badgeClass(): string { return match($this) { self::Draft => 'bg-gray-200', self::Confirmed => 'bg-blue-500', self::Shipped => 'bg-green-500', }; }
遍历枚举所有项并渲染列表
这是管理后台展示状态选项、导出枚举字典、生成 API 文档时的刚需操作。
① 调用 ::cases() 获取完整实例数组:$all = OrderStatus::cases();
② foreach 遍历,访问每个实例的 name 和(若为背书枚举)value:foreach ($all as $item) { printf('%s → %s%s', $item->name, $item->value ?? '(无值)', PHP_EOL); }
③ 输出示例:
Draft → draft<br>Confirmed → confirmed<br>Shipped → shipped
这一步操作起来很简单,直接把循环代码复制进你的命令行脚本或调试页面就能看到结果。


















