PHP 8 - 枚举

PHP 8 - 枚举 首页 / PHP7+入门教程 / PHP 8 - 枚举

像往常一样,使用无涯教程的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,
] */

# 枚举对象

无涯教程已经提到枚举值表示为对象,实际上这些是单例对象。这意味着您可以与它们进行比较:

链接:https://www.learnfk.comhttps://www.learnfk.com/php7+/php-enums.html

来源:LearnFk无涯教程网

$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 函数,它是它的名字所建议的。

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

从0开始学大数据 -〔李智慧〕

Nginx核心知识150讲 -〔陶辉〕

Flutter核心技术与实战 -〔陈航〕

图解 Google V8 -〔李兵〕

Flink核心技术与实战 -〔张利兵〕

Go 语言项目开发实战 -〔孔令飞〕

如何讲好一堂课 -〔薛雨〕

超级访谈:对话汤峥嵘 -〔汤峥嵘〕

Python实战 · 从0到1搭建直播视频平台 -〔Barry〕

好记忆不如烂笔头。留下您的足迹吧 :)