目录
什么是枚举?
枚举是一种特殊的数据类型,允许定义一组命名的常量值。在 PHP 8.1 之前,开发者通常使用类常量或数组来模拟枚举,但 PHP 8.1 引入了原生枚举支持,提供了更好的类型安全性和功能。
基本语法
// 定义纯值枚举
enum Status: string {
case DRAFT = 'draft';
case PUBLISHED = 'published';
case ARCHIVED = 'archived';
}
// 使用枚举
$status = Status::DRAFT;
// 获取枚举值
echo $status->value; // 输出: draft
// 通过值获取枚举实例
$status = Status::from('draft');
// 或者安全获取(失败时返回 null)
$status = Status::tryFrom('draft');
纯值枚举(Pure Enums)
// 整数类型的枚举
enum Priority: int {
case LOW = 1;
case MEDIUM = 2;
case HIGH = 3;
case CRITICAL = 4;
}
// 字符串类型的枚举
enum Color: string {
case RED = '#FF0000';
case GREEN = '#00FF00';
case BLUE = '#0000FF';
}
// 使用示例
$priority = Priority::HIGH;
echo $priority->value; // 输出: 3
echo $priority->name; // 输出: HIGH
// 类型提示
function setPriority(Priority $priority): void {
echo "Setting priority to: {$priority->value}\n";
}
setPriority(Priority::CRITICAL);
回退枚举(Backed Enums)
// 回退枚举可以具有标量值(int 或 string)
enum HttpStatus: int {
case OK = 200;
case CREATED = 201;
case BAD_REQUEST = 400;
case NOT_FOUND = 404;
case SERVER_ERROR = 500;
}
// 实用方法
$status = HttpStatus::from(404);
echo $status->name; // NOT_FOUND
echo $status->value; // 404
// 遍历所有枚举值
foreach (HttpStatus::cases() as $case) {
echo "{$case->name} = {$case->value}\n";
}
枚举方法
枚举可以包含方法和静态方法:
enum Suit: string {
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',
};
}
// 静态方法
public static function random(): self {
$cases = self::cases();
return $cases[array_rand($cases)];
}
}
// 使用示例
$suit = Suit::HEARTS;
echo $suit->color(); // 输出: red
$randomSuit = Suit::random();
echo $randomSuit->value;
接口实现
枚举可以实现接口:
interface Describable {
public function description(): string;
}
enum UserRole: string implements Describable {
case ADMIN = 'admin';
case EDITOR = 'editor';
case VIEWER = 'viewer';
public function description(): string {
return match($this) {
self::ADMIN => '具有完全访问权限',
self::EDITOR => '可以创建和编辑内容',
self::VIEWER => '只能查看内容',
};
}
}
// 使用示例
$role = UserRole::ADMIN;
echo $role->description(); // 输出: 具有完全访问权限
实用示例
示例 1:订单状态管理
enum OrderStatus: string {
case PENDING = 'pending';
case PROCESSING = 'processing';
case SHIPPED = 'shipped';
case DELIVERED = 'delivered';
case CANCELLED = 'cancelled';
public function isCompleted(): bool {
return in_array($this, [self::DELIVERED, self::CANCELLED]);
}
public function canTransitionTo(self $status): bool {
return match($this) {
self::PENDING => in_array($status, [self::PROCESSING, self::CANCELLED]),
self::PROCESSING => in_array($status, [self::SHIPPED, self::CANCELLED]),
self::SHIPPED => $status === self::DELIVERED,
default => false,
};
}
}
// 使用
$status = OrderStatus::PENDING;
if ($status->canTransitionTo(OrderStatus::PROCESSING)) {
echo "可以转换到处理状态\n";
}
示例 2:权限系统
enum Permission: int {
case READ = 1; // 0001
case WRITE = 2; // 0010
case DELETE = 4; // 0100
case ADMIN = 7; // 0111 (READ|WRITE|DELETE)
public function hasPermission(self $permission): bool {
return ($this->value & $permission->value) === $permission->value;
}
public function addPermission(self $permission): self {
return self::from($this->value | $permission->value);
}
}
// 使用
$userPerm = Permission::READ->addPermission(Permission::WRITE);
echo $userPerm->hasPermission(Permission::WRITE) ? '有写权限' : '无写权限';
示例 3:配置管理
enum Environment: string {
case LOCAL = 'local';
case STAGING = 'staging';
case PRODUCTION = 'production';
public function config(): array {
return match($this) {
self::LOCAL => [
'debug' => true,
'cache' => false,
'db_host' => 'localhost',
],
self::STAGING => [
'debug' => true,
'cache' => true,
'db_host' => 'staging.db.example.com',
],
self::PRODUCTION => [
'debug' => false,
'cache' => true,
'db_host' => 'production.db.example.com',
],
};
}
}
// 使用
$env = Environment::from($_ENV['APP_ENV'] ?? 'local');
$config = $env->config();
注意事项
- 枚举是单例的:每个枚举值都是单例实例
- 不可序列化:枚举不能直接序列化,但可以通过
value属性间接实现 - 不支持动态创建:不能在运行时动态创建枚举实例
- 继承限制:枚举不能继承其他类,但可以实现接口
- 魔术方法:枚举支持
__call、__callStatic、__invoke方法
与类常量的对比优势:
| 特性 | 枚举 | 类常量 |
|---|---|---|
| 类型安全 | ✅ 是 | ❌ 否 |
| 自动完成 | ✅ 好 | ⚠️ 有限 |
| 方法支持 | ✅ 是 | ❌ 否 |
| 接口实现 | ✅ 是 | ❌ 否 |
| 遍历所有值 | ✅ cases() | ⚠️ 需要反射 |
性能提示:
// 高效比较(使用 identity operator)
if ($status === Status::PUBLISHED) {
// 因为枚举是单例,所以可以使用 ===
}
// 在 switch/match 中使用
$message = match($status) {
Status::DRAFT => '草稿',
Status::PUBLISHED => '已发布',
Status::ARCHIVED => '已归档',
};
PHP 8.1 枚举提供了类型安全、可读性强且功能丰富的解决方案,适用于需要固定值集合的各种场景。


被折叠的 条评论
为什么被折叠?



