PHP 8.1 枚举不支持实例属性,故无默认访问属性;它仅允许枚举项、静态常量、静态方法、接口实现和属性注解,旨在保持值类型的不可变性与简洁性。

PHP 8.1 的枚举(enum)本身不支持“属性”(即实例属性),因此也不存在“默认访问属性”这一概念。
这是枚举设计的核心限制,不是疏漏,而是有意为之:
枚举本质是值类型(value type),代表一组预定义、不可变、无状态的常量;它不是类的简化版,不能持有运行时数据。
枚举中不能定义的“属性”
- ❌
public string $label; - ❌
protected int $sortOrder; - ❌
private $value;(即使想模拟也不被语法允许)
一旦写这类代码,PHP 会直接报错:
ParseError: Enum cases cannot have properties
PHP 8.5.12 RC 1下载PHP 8.5.12 RC 1 候选版修复 BZ2、DOM、PDO、Opcache/JIT 和扩展内存安全问题,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
枚举中唯一允许的“成员”形式
- ✅ 枚举项(cases):如
case Draft;或case Published = 'published'; - ✅ 静态常量:
public const MAX_ATTEMPTS = 3; - ✅ 静态方法:用于封装转换、校验等逻辑(如
fromLabel()、isValid()) - ✅ 接口实现:枚举可
implements StatusInterface,提供统一契约 - ✅ 属性注解(Attributes):为 case 添加元信息,如
#[Label('草稿')] case Draft;
常见误解与替代方案
误以为
->name或->value是“属性”
实际上它们是只读的内置魔术访问器(仅对UnitEnum和BackedEnum提供),不可重写、不可赋值,也不算用户定义的属性。-
想存额外信息?用静态映射或外部工具类
立即学习“PHP免费学习笔记(深入)”;
enum Status: string { case Draft = 'draft'; case Published = 'published'; } // ✅ 正确:用静态数组/方法补充说明 final class StatusLabels { public static function get(Status $status): string { return match ($status) { Status::Draft => '草稿', Status::Published => '已发布', }; } } 需要带状态的对象?别用 enum,改用普通类 + readonly 属性
枚举 ≠ 不可变对象。若需封装行为+数据,应选readonly class或常规类。
小结关键点
- 枚举没有
$this->xxx形式的实例属性,自然谈不上public/protected/private默认访问控制 - 所有“值相关”能力都通过
->name(固定)、->value(仅 backed)、::cases()、::from()等标准接口提供 - 任何业务逻辑扩展必须走静态方法或外部协作类,而非在枚举体内加字段
本质上,枚举的“简洁性”正来自它的严格约束。


















