PHP 8 - 枚举介绍
他们终于即将到来 - 内置对枚举的支持将在 php 8.1 中添加。
像往常一样,使用我的PHP函数帖子,我们从高级概述开始,枚举是什么样的:
enum Status
{
case DRAFT;
case PUBLISHED;
case ARCHIVED;
}
枚举的好处是它们代表了一个常量值的集合,但最重要的是可以输入这些值,如:
class BlogPost
{
public function __construct(
public Status $status,
) {}
}
在此示例中,创建枚举并将其传递给 blogpost
如下所示:
$post = new BlogPost(Status::DRAFT);
这是基本的方式,因为你可以看到没有任何复杂的事情。
# 枚举方法
枚举可以定义方法,就像类一样。这是一个非常强大的函数,特别是与 match
运算符配合使用:
enum Status
{
case DRAFT;
case PUBLISHED;
case ARCHIVED;
public function color(): string
{
return match($this)
{
Status::DRAFT => 'grey',
Status::PUBLISHED => 'green',
Status::ARCHIVED => 'red',
};
}
}
方法可以如此使用:
$status = Status::ARCHIVED;
$status->color(); // 'red'
允许静态方法:
enum Status
{
// …
public static function make(): Status
{
// …
}
}
您也可以使用 self
:
enum Status
{
// …
public function color(): string
{
return match($this)
{
self::DRAFT => 'grey',
self::PUBLISHED => 'green',
self::ARCHIVED => 'red',
};
}
}
# 枚举接口
枚举可以实现接口,就像普通类一样:
interface HasColor
{
public function color(): string;
}
enum Status implements HasColor
{
case DRAFT;
case PUBLISHED;
case ARCHIVED;
public function color(): string { /* … */ }
}
# 枚举值
枚举值由内部的对象表示,但如果您愿意,可以为它们分配一个值;
enum Status: string
{
case DRAFT = 'draft';
case PUBLISHED = 'published';
case ARCHIVED = 'archived';
}
注意枚举定义中的类型声明。它表示所有枚举值都是给定类型的。您也可以使其成为 int
。请注意,仅 int
和 String
被允许作为枚举值。
enum Status: int
{
case DRAFT = 1;
case PUBLISHED = 2;
case ARCHIVED = 3;
}
键入枚举的技术术语被称为"backed enums",因为它们被更简单的值"backed"。如果您决定分配枚举值,则所有情况都应具有值。
# 带接口的枚举
如果您要合并支持的枚举和接口,则枚举类型必须直接在枚举名称之后,在Implements关键字之前。
enum Status: string implements HasColor
{
case DRAFT = 'draft';
case PUBLISHED = 'published';
case ARCHIVED = 'archived';
// …
}
# 序列化枚举
如果要为enum分配值,则可能需要一种序列化和反序列化它们的方法。序列化意味着您需要一种访问枚举值的方法。这是通过只读公共属性完成的:
$value = Status::PUBLISHED->value; // 2
可以通过使用Enum::from
$status = Status::from(2); // Status::PUBLISHED
还有一个 tryfrom
,它返回 null
如果通过了未知值。如果您使用 from
将存在异常。
$status = Status::from('unknown'); // ValueError
$status = Status::tryFrom('unknown'); // null
请注意,您还可以对枚举使用内置的序列化(serialize)和反序列化(unsermalize)功能。此外,您可以将json_encode与支持的枚举结合使用,其结果将是枚举值。可以通过实现JsonSerializable来覆盖此行为。
# Listing enum values
您可以使用静态的 Enum::cases()
方法获取枚举中所有可用值的列表:
Status::cases();
/* [
Status::DRAFT,
Status::PUBLISHED,
Status::ARCHIVED
] */
请注意,此数组包含实际的枚举对象:
array_map(
fn(Status $status) => $status->color(),
Status::cases()
);
使用支持的枚举时,数组键将包含枚举值:
Status::cases();
/* [
'draft' => Status::DRAFT,
'published' => Status::PUBLISHED,
'archived' => Status::ARCHIVED,
] */
# 枚举对象
我已经提到枚举值表示为对象,实际上这些是单例对象。这意味着您可以与它们进行比较:
$statusA = Status::PENDING;
$statusB = Status::PENDING;
$statusC = Status::ARCHIVED;
$statusA === $statusB; // true
$statusA === $statusC; // false
$statusC instanceof Status; // true
# 枚举作为数组键
由于枚举值实际上是对象,因此目前无法将它们用作数组键。以下将导致错误:
$list = [
Status::DRAFT => 'draft',
// …
];
这意味着您只能在SplObjectStorage和WeakMaps中将枚举用作键。
# Traits
枚举可以像类一样使用特征,但有更多限制。您不允许覆盖内置的枚举方法,并且它们不能包含类属性-枚举中禁止使用这些属性。
# Reflection and attributes
正如预期的那样,有几个用于处理枚举的反射类: Reflectionenum
, ReflectenumunitCase
和 ReflecteneNumbackedCase
。还有一个新的 enum_exists
函数,它是它的名字所建议的。
链接:https://www.learnfk.com/article-php-enums
来源:Learnfk无涯私塾网