PHP中的枚举:从switch到Enum(完整指南)

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

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

开始课程

为什么“Enumerations on PHP”是一个价值百万的问题?

\n\n

如果你曾经搜索过“enumerations on PHP”,你就会知道:在PHP 8.1发布之前,这个话题简直是一场冒险。开发者们用常量、抽象类和巧妙的trait发明了各种“轮子”。Stack Overflow上充斥着诸如“如何在PHP中模拟Enum?”之类的问题,而答案则收获了数百个赞。

\n\n

但时代变了。从PHP 8.1开始,枚举(Enum)成为了语言的原生部分。这不仅仅是语法糖——它是一个用于编写干净、安全且自文档化代码的强大工具。

\n\n

在本文中,我们将全面解析:从经典的常量方法到现代的Enum,并附有真实示例和最佳实践。开始吧!

\n\n

问题:PHP 8.1之前的开发者是如何生存的

\n\n

在原生枚举出现之前,我们主要有两种方法:类常量和带有抽象类的“权宜之计”。我们来看看这两种方法。

\n\n

方法#1:类常量(最流行)

\n\n
class OrderStatus {\n    const PENDING = 'pending';\n    const PROCESSING = 'processing';\n    const SHIPPED = 'shipped';\n    const DELIVERED = 'delivered';\n    const CANCELLED = 'cancelled';\n}\n\n// 使用\n$status = OrderStatus::PENDING;\nif ($status === OrderStatus::PROCESSING) {\n    echo '订单正在处理';\n}
\n\n

优点:简单、易懂、IDE自动补全。

\n

缺点:缺乏类型检查。任何人都可以传递字符串'invalid_status'——而PHP不会报错。

\n\n

方法#2:抽象类 + 私有构造函数

\n\n

高级开发者更进一步:

\n\n
abstract class OrderStatus {\n    private function __construct() {}\n    \n    public static function pending(): self {\n        return new class extends OrderStatus {};\n    }\n    public static function processing(): self {\n        return new class extends OrderStatus {};\n    }\n    // ... 其余状态\n}
\n\n

这虽然可行,但代码变得臃肿。而且这仍然是模拟,而不是真正的语言支持。

\n\n

PHP 8.1中的原生Enum:一场革命

\n\n

随着PHP 8.1的发布,“enumerations on PHP”的问题被一劳永逸地解决了。现在,枚举是完整的类型,它们:

\n\n
    \n
  • 支持严格类型检查
  • \n
  • 拥有内置方法(name、value、cases())
  • \n
  • 可以实现接口
  • \n
  • 支持trait
  • \n
  • 与match和switch集成
  • \n
\n\n

PHP中Enum的基本语法

\n\n
enum OrderStatus {\n    case Pending;\n    case Processing;\n    case Shipped;\n    case Delivered;\n    case Cancelled;\n}\n\n// 使用\n$status = OrderStatus::Pending;\necho $status->name; // 'Pending'
\n\n

简单而优雅。但这只是开始。

\n\n

Enum的类型:纯枚举和带值的枚举

\n\n

PHP支持两种类型的枚举:

\n\n

1. Pure Enum(纯枚举)

\n

不绑定到特定值。非常适合标志、状态、类型。

\n\n
enum UserRole {\n    case Admin;\n    case Editor;\n    case Viewer;\n}\n\nfunction checkAccess(UserRole $role): bool {\n    return match($role) {\n        UserRole::Admin => true,\n        UserRole::Editor => true,\n        UserRole::Viewer => false,\n    };\n}
\n\n

2. Backed Enum(带值的枚举)

\n

当需要将枚举与特定值(字符串或整数)关联时使用。

\n\n
enum OrderStatus: string {\n    case Pending = 'pending';\n    case Processing = 'processing';\n    case Shipped = 'shipped';\n    case Delivered = 'delivered';\n    case Cancelled = 'cancelled';\n}\n\n// 获取值\n$status = OrderStatus::Shipped;\necho $status->value; // 'shipped'\n\n// 从值创建\n$

博客

书籍推荐