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无涯私塾网


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM