PHP中的枚举:如何使用枚举及代码示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

PHP中的枚举:从混乱到有序

\n\n

你是否曾经写过这样的代码:订单状态用字符串 'new'、'paid'、'shipped' 存储?然后因为拼写错误 'shippped' 而遇到bug?或者向函数 getOrderByStatus('Active') 传参,而函数却期待 'active'?很熟悉吧?那么这篇文章就是为你准备的。

\n\n

长期以来,PHP没有原生的枚举。开发者们想尽办法:使用类常量、数组,甚至占位注释。但随着PHP 8.1的发布,一切都变了。现在我们有了完整的PHP枚举——一个强大的工具,能让代码更清晰、更安全、更易理解。

\n\n

在本指南中,我们将从A到Z全面讲解PHP枚举:从基本语法到高级技巧。你将学习如何创建枚举、使用枚举、比较枚举,以及在真实项目中应用。开始吧!

\n\n

PHP中的枚举是什么?

\n\n

枚举是一种数据类型,其值被限制在一组预定义的选项中。简单来说:你定义一组可能的选项,变量只能取其中之一。没有随意的字符串,没有未经验证的值。

\n\n

在PHP 8.1中,枚举被实现为特殊的类。每个值都是一个对象,而不仅仅是常量。这带来了许多优势:

\n\n
    \n
  • 强类型——编译器不会允许 'pending' 代替 Status::Pending
  • \n
  • 安全性——没有意外的拼写错误
  • \n
  • 可读性——代码不言自明
  • \n
  • IDE支持——自动补全完美工作
  • \n
\n\n

PHP中枚举的语法

\n\n

在PHP中创建枚举很简单。使用关键字 enum:

\n\n
<?php\n\nenum OrderStatus\n{\n    case New;\n    case Pending;\n    case Processing;\n    case Shipped;\n    case Delivered;\n    case Cancelled;\n}\n
\n\n

现在我们可以将 OrderStatus 用作类型:

\n\n
<?php\n\nfunction updateOrderStatus(OrderStatus $status): void\n{\n    // 处理状态\n}\n\n// 传递值:\nupdateOrderStatus(OrderStatus::Shipped);\n
\n\n

尝试传递字符串 'shipped'——PHP会抛出类型错误。这就是PHP枚举的魔力所在。

\n\n

后备枚举

\n\n

通常我们需要将每个用例与特定值关联——例如,用于数据库的数字或字符串。在PHP中,这称为后备枚举:

\n\n
<?php\n\nenum OrderStatus: string\n{\n    case New = 'new';\n    case Pending = 'pending';\n    case Processing = 'processing';\n    case Shipped = 'shipped';\n    case Delivered = 'delivered';\n    case Cancelled = 'cancelled';\n}\n
\n\n

现在每个用例都有一个字符串值。你可以通过 value 属性获取它:

\n\n
<?php\n\n$status = OrderStatus::Shipped;\necho $status->value; // 'shipped'\n
\n\n

也可以从值反向创建用例:

\n\n
<?php\n\n$status = OrderStatus::from('shipped');\necho $status->name; // 'Shipped'\n
\n\n

如果未找到值,from() 方法会抛出异常。如果想获取 null,请使用 tryFrom()。

\n\n

枚举中的方法:枚举内部的行为

\n\n

PHP枚举的一个很酷的功能是可以在枚举内部直接添加方法。这将枚举从简单的常量列表转变为带有逻辑的完整对象。

\n\n
<?php\n\nenum OrderStatus: string\n{\n    case New = 'new';\n    case Pending = 'pending';\n    case Processing = 'processing';\n    case Shipped = 'shipped';\n    case Delivered = 'delivered';\n    case Cancelled = 'cancelled';\n\n    public function label(): string                

博客

书籍推荐