PHP 枚举
最后修改于 2025 年 4 月 16 日
PHP enum 关键字引入了枚举,这是一种特殊的类。枚举表示一组固定的可能值,使代码更具可读性和类型安全性。它们是在 PHP 8.1 中添加的。
基本定义
一个 enum 定义了一个自定义类型,其可能值的集合是有限的。每个可能的值被称为 "case"。枚举可以拥有方法并像常规类一样实现接口。
有两种类型的枚举:纯枚举(没有值)和带值枚举(带有标量值)。带值枚举必须声明其值类型(int 或 string)。
语法:enum EnumName { case Case1; case Case2; } 用于纯枚举。对于带值枚举:enum EnumName: type { case Case1 = value; }。
基本枚举声明
此示例演示了一个简单的纯枚举,它代表 HTTP 方法。
<?php
declare(strict_types=1);
enum HttpMethod {
case GET;
case POST;
case PUT;
case DELETE;
}
$method = HttpMethod::POST;
if ($method === HttpMethod::POST) {
echo "This is a POST request.";
}
该代码定义了一个枚举,其中包含四个 HTTP 方法 case。我们创建一个枚举变量并将其与一个 case 进行比较。枚举提供了优于使用字符串或整数的类型安全。每个 case 都是枚举类型的一个实例。
带值枚举
此示例显示了一个带值枚举,其中包含状态码的字符串值。
<?php
declare(strict_types=1);
enum Status: string {
case PENDING = 'pending';
case APPROVED = 'approved';
case REJECTED = 'rejected';
}
$status = Status::APPROVED;
echo "Status: " . $status->value;
枚举为每个 case 声明字符串值。我们使用 value 属性访问该值。带值枚举必须声明所有带有值的 case。值在枚举中必须是唯一的。
枚举方法
此示例演示了向枚举添加方法。
<?php
declare(strict_types=1);
enum Direction {
case NORTH;
case SOUTH;
case EAST;
case WEST;
public function opposite(): self {
return match($this) {
self::NORTH => self::SOUTH,
self::SOUTH => self::NORTH,
self::EAST => self::WEST,
self::WEST => self::EAST,
};
}
}
$dir = Direction::NORTH;
$opposite = $dir->opposite();
echo "Opposite of NORTH is " . $opposite->name;
枚举定义了一个 opposite 方法,该方法返回另一个枚举 case。我们使用模式匹配与 match 来确定相反的方向。方法可以通过 $this 访问当前 case。
枚举实现接口
此示例显示了一个实现接口的枚举。
<?php
declare(strict_types=1);
interface Colorful {
public function color(): string;
}
enum Suit: string implements Colorful {
case HEARTS = 'H';
case DIAMONDS = 'D';
case CLUBS = 'C';
case SPADES = 'S';
public function color(): string {
return match($this) {
self::HEARTS, self::DIAMONDS => 'Red',
self::CLUBS, self::SPADES => 'Black',
};
}
}
$card = Suit::DIAMONDS;
echo "Card color: " . $card->color();
枚举实现了 Colorful 接口,其中包含一个 color 方法。每个 case 必须实现接口方法。这允许枚举参与类型层次结构。该方法根据花色返回不同的颜色。
枚举在 Switch 语句中
此示例演示了在 switch 语句中使用枚举。
<?php
declare(strict_types=1);
enum UserRole {
case ADMIN;
case EDITOR;
case SUBSCRIBER;
case GUEST;
}
function getPermissions(UserRole $role): string {
switch ($role) {
case UserRole::ADMIN:
return "All permissions";
case UserRole::EDITOR:
return "Edit content";
case UserRole::SUBSCRIBER:
return "View premium content";
default:
return "Basic viewing";
}
}
echo getPermissions(UserRole::EDITOR);
该函数接受一个枚举参数,并根据其值进行切换。每个 case 处理不同的枚举值。默认 case 处理任何未指定的值。枚举与 switch 语句自然配合使用以进行控制流。
枚举静态方法
此示例显示了枚举中的静态方法,用于创建和验证。
<?php
declare(strict_types=1);
enum Size: int {
case SMALL = 1;
case MEDIUM = 2;
case LARGE = 3;
public static function fromValue(int $value): self {
return match($value) {
1 => self::SMALL,
2 => self::MEDIUM,
3 => self::LARGE,
default => throw new ValueError("Invalid size value"),
};
}
public static function isValid(int $value): bool {
return $value >= 1 && $value <= 3;
}
}
$size = Size::fromValue(2);
echo "Size: " . $size->name;
echo "Is 4 valid? " . (Size::isValid(4) ? 'Yes' : 'No');
枚举提供了静态方法,用于从值创建实例和验证值。fromValue 为无效值抛出异常。静态方法在枚举类本身而不是实例上调用。
带有属性的枚举
此示例演示了将 PHP 属性与枚举 case 一起使用。
<?php
declare(strict_types=1);
#[Attribute]
class Description {
public function __construct(public string $text) {}
}
enum LogLevel {
#[Description("Debug-level messages")]
case DEBUG;
#[Description("Informational messages")]
case INFO;
#[Description("Warning conditions")]
case WARNING;
#[Description("Error conditions")]
case ERROR;
}
$reflection = new ReflectionEnum(LogLevel::class);
$case = $reflection->getCase('DEBUG');
$attrs = $case->getAttributes(Description::class);
foreach ($attrs as $attr) {
echo $attr->newInstance()->text;
}
该代码定义了一个自定义属性并将其应用于枚举 case。我们使用反射在运行时读取属性值。属性提供有关枚举 case 的元数据。此模式对于文档或框架集成非常有用。
最佳实践
- 命名: 对枚举名称使用单数名词(Status 而不是 Statuses)。
- 值: 除非你需要标量值,否则更倾向于纯枚举。
- 比较: 始终对枚举使用严格比较 (===)。
- 方法: 保持枚举方法专注于枚举的领域。
- Case: 在不明显时,记录每个 case 的用途。
来源
本教程涵盖了 PHP 枚举,并提供了实际示例,展示了枚举声明、方法、接口和高级功能。
作者
列出 所有 PHP 教程。