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,
] */

# 枚举对象

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

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

这一章《PHP 8 - 枚举》你学到了什么?在下面做个笔记吧!做站不易,你的分享是对我们最大的支持,感谢!😊

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

相关推荐

趣谈网络协议 -〔刘超 - 〕

如何设计一个秒杀系统 -〔许令波 - 〕

DDD实战课 -〔欧创新 - 〕

人人都用得上的写作课 -〔涵柏 - 〕

如何使用正则表达式替换除 PHP 中第一个字符之外的所有字符?

如何在 PHP 中使用 * 等式字符串验证括号

curl_close 后未保存 PHP cURL cookie

PHP |将特定的德国日期格式解析为 yyyy-mm-dd

数组洗牌和undo撤消

WooCommerce 获取产品属性分类值

视频推荐

PHP7+ - 41.回调函数 更多视频教程 »