php 8.2 枚举需严格遵循刚性路径:json_encode() 必须显式用 ->value;::from() 抛异常、::tryfrom() 返回 null 且须判空;遍历用 cases() 而非数组;match() 必须穷举所有 case,不可依赖 default。

PHP 8.2 没有新增大量内置函数,但关键几个的用法和边界条件变了——尤其涉及枚举、只读类、类型推导时,错一个参数或漏一次校验,运行时就崩。
json_encode() 处理 BackedEnum 必须显式取 ->value
直接 json_encode(OrderStatus::Shipped) 输出的是 {},不是 "shipped"。因为枚举是对象,而 json_encode() 对未实现 JsonSerializable 的对象默认序列化为空对象。
- 正确写法:
json_encode($status->value)或json_encode(['status' => $status->value]) - 别依赖自动转换:PHP 不会为枚举自动调用
->value,哪怕它是BackedEnum - 如果要输出名称(如
"Shipped")而非值,得手动映射:$status->name,但注意这和 API 传输惯例通常冲突
::from() 和 ::tryFrom() 别混用场景
两者都用于从标量值重建枚举实例,但错误处理策略完全不同:
-
HttpStatus::from('404'):值不存在时抛出ValueError,适合强约束上下文(如路由匹配、配置加载) -
HttpStatus::tryFrom('999'):值不存在时返回null,适合宽松解析(如用户提交的表单字段、第三方 webhook payload) - 别对
tryFrom()的返回值直接调用方法——先判空:$status = HttpStatus::tryFrom($input); if ($status !== null) { ... }
遍历所有枚举项必须用 cases(),别手写数组
想生成下拉选项、校验白名单、初始化缓存?别再维护一个 ['pending', 'shipped', 'delivered'] 数组了。
- 纯枚举(
enum Status { case Pending; ... })只能用Status::cases()获取实例数组 - 背书枚举(
enum Status: string { case Pending = 'pending'; ... })同样用cases(),返回的是带->value和->name的对象列表 - 错误示范:
array_keys(get_class_vars(Status::class))—— 这根本拿不到case,PHP 类常量机制和枚举无关
match() 表达式必须覆盖全部 case,否则报错
这是 PHP 8.2 枚举最易忽略的编译期限制:用 match() 分支处理枚举时,必须穷举所有 case,不能靠 default 偷懒。
- 合法:
match($status) { OrderStatus::Pending => 'wait', OrderStatus::Shipped => 'sent', OrderStatus::Delivered => 'done' } - 非法(即使你确定只有这三种状态):
match($status) { OrderStatus::Pending => 'wait', default => 'unknown' }—— 会触发Fatal error: Unhandled match expression value - 如果未来会扩展枚举项,又不想每次改
match,就用if/else或提前assert($status instanceof OrderStatus)+ 抛异常兜底
tryFrom() 防崩溃,内部状态流转用 from() 保契约,序列化一律走 ->value,遍历永远靠 cases() —— 这些不是约定,是 PHP 8.2 枚举机制本身决定的刚性路径。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











