您的当前位置:首页>全部文章>文章详情

【PHP】PHP8.1新特性大讲解之Enums枚举

CrazyPanda发表于:2024-01-03 23:59:57浏览:451次TAG:

PHP 8.1:枚举

它们终于来了——PHP 8.1中将添加对枚举的内置支持!有些人可能认为他们早就应该这样做了,但你没有听到我的抱怨;我很高兴他们做到了!这篇文章致力于深入研究新添加的功能。

像往常一样,在我的 PHP 功能帖子中,我们首先对枚举的外观进行高级概述:

enum Status
{
    case DRAFT;
    case PUBLISHED;
    case ARCHIVED;
}

枚举的好处是它们代表了一组常量值,但最重要的是这些值可以被键入,如下所示:

class BlogPost
{
    public function __construct(
        public Status $status,
    ) {}
}

在这个例子中,创建一个枚举并将其传递给 aBlogPost看起来像这样:

$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. 请注意, onlyint和string允许作为枚举值。

enum Status: int
{
    case DRAFT = 1;
    case PUBLISHED = 2;
    case ARCHIVED = 3;
}

类型枚举的技术术语称为“支持枚举”,因为它们由更简单的值“支持”。如果您决定分配枚举值,则所有案例都应该有一个值。你不能混合和匹配它们。没有“支持”的枚举被称为“纯枚举”。

#带接口的支持枚举

如果您将支持的枚举和接口结合使用,则枚举类型必须直接位于枚举名称之后,implements关键字之前。

enum Status: string implements HasColor
{
    case DRAFT = 'draft';
    case PUBLISHED = 'published';
    case ARCHIVED = 'archived';
     
    // …
}

#序列化支持的枚举

如果您要为枚举案例分配值,您可能需要一种方法来序列化和反序列化它们。序列化它们意味着您需要一种访问枚举值的方法。这是通过只读公共属性完成的:

$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和unserialize函数。此外,您可以json_encode与支持的枚举结合使用,其结果将是枚举值。可以通过实现来覆盖此行为JsonSerializable。

#列出枚举值

您可以使用静态方法获取枚举中所有可用案例的列表:Enum::cases()

Status::cases();
/* [
    Status::DRAFT,
    Status::PUBLISHED,
    Status::ARCHIVED
] */

请注意,此数组包含实际的枚举对象:

array_map(
    fn(Status $status) => $status->color(),
    Status::cases()
);

#枚举是对象

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

$statusA = Status::PENDING;
$statusB = Status::PENDING;
$statusC = Status::ARCHIVED;
$statusA === $statusB; // true
$statusA === $statusC; // false
$statusC instanceof Status; // true

#枚举作为数组键

由于枚举值实际上是对象,因此目前无法将它们用作数组键。以下将导致错误:

$list = [
    Status::DRAFT => 'draft',
    // …
];

有一个 RFC来改变这种行为,但它还没有被投票。

这意味着您只能使用枚举作为SplObjectStorage和 中的键WeakMaps。

#性状

枚举可以像类一样使用特征,但有更多限制。不允许覆盖内置的枚举方法,并且它们不能包含类属性 - 枚举中禁止使用这些属性。

#反射和属性

正如预期的那样,添加了一些反射类来处理枚举:ReflectionEnum、ReflectionEnumUnitCase和ReflectionEnumBackedCase。还有一个新enum_exists功能,正如它的名字所暗示的那样。

就像普通的类和属性一样,枚举及其案例可以使用attributes进行注释。请注意,TARGET_CLASS过滤器还将包括枚举。

最后一件事:枚举也有一个只读属性,RFC 提到这是一个实现细节,应该只用于调试目的。不过还是值得一提的。$enum->name


猜你喜欢

【PHP】php二维数组排序
        PHP作为一种常用的Web编程语言,在不同的应用场景下,对数组的处理是不可避免的。而对于数组排序,也是开发时经常面对的一个问题。本文将介绍如何对二维数组进行排序。一、二维数组排序概述在PHP中,二维数组是由多个一维数组链接而成的复合数组,也就是说,它不仅有行的概念,还有列的概念。当需要对二维数组进行排序时,通常需要对其中某一列进行排序。这时候需要使用PHP提供的函数来进行排序。二、对二维数组进行排序的方法1.使用usort()函数u
发表于:2023-12-14 浏览:376 TAG:
【PHP】php加密算法有哪些
php加密算法有MD5算法、SHA算法、AES算法、RSA算法、Base64编码、DES算法、RC4算法、Blowfish算法等。详细介绍:1、MD5算法,用于将任意长度的数据转换为固定长度的哈希值,在PHP中可以使用md5()函数来计算字符串的MD5哈希值;2、SHA算法,包括SHA-1、SHA-256、SHA-512等,这些算法在PHP中都有对应的函数;3、AES算法等等。本教程操作系统:windows10系统、PHP8.1.3版本、Dell G3电脑。PHP是一种广泛使用的服务器
发表于:2023-12-06 浏览:296 TAG:
【PHP】intervention/image设置文字竖排显示
在使用 intervention/image 库时,要让文字竖排显示,可以通过设置文字的样式和使用 rotate 方法将文字旋转90度来实现。以下是一个示例代码:use Intervention\Image\ImageManagerStatic as Image;   // 初始化ImageManager $imageManager = new Image();   // 加载背景图片 $back
发表于:2024-04-08 浏览:321 TAG:
【PHP】什么是微服务架构
随着互联网的不断发展,越来越多的网站和应用程序应运而生。而对于开发者来说,如何快速高效地构建应用程序,是一个重要的挑战。其中,微服务架构已经成为了一个越来越受欢迎的解决方案。而php作为一种最受欢迎的web开发语言之一,也已经成为了很多开发者在构建微服务架构时的首选语言。本文将为大家介绍PHP如何应用于微服务架构,帮助大家更好地理解微服务架构以及如何使用PHP构建高效的微服务应用程序。什么是微服务架构?微服务架构(Microservices Architecture)是一种构建分布式应用程序的软
发表于:2024-05-23 浏览:288 TAG:
【PHP】设计模式的六大原则
设计模式的六大原则是指导软件开发设计的核心原则,它们帮助开发人员创建可维护、可扩展和灵活的软件系统。这些原则包括: ‌    单一职责原则(Single Responsibility Principle, SRP):一个类应该只有一个引起它变化的原因。这有助于减少类与类之间的耦合,提高类的内聚性和可读性。 ‌    开闭原则(Open-Closed Principle, OCP):软件实体(如类、
发表于:2024-07-16 浏览:271 TAG:
【PHP】ThinkPHP 资源路由的简单使用,restfull风格API
一、资源控制器资源控制器可以轻松的创建RESTFul资源控制器,可以通过命令行生成需要的资源控制器,例如生成index应用的TestR资源控制器使用:php think make:controller index@TestR # php think make:controller 应用名@资源控制名或者使用完整的命名空间生成php think make:controller app\index\c
发表于:2024-05-24 浏览:249 TAG:
【PHP】thinkphp设计模式讲解
一、设计模式简介  首先我们来认识一下什么是设计模式:  设计模式是一套被反复使用、容易被他人理解的、可靠的代码设计经验的总结。  设计模式不是Java的专利,我们用面向对象的方法在PHP里也能很好的使用23种设计模式。  那么我们常说的架构、框架和设计模式有什么关系呢?  架构是一套体系结构,是项目的整体解决方案;框架是可供复用的半成品软件,是具体程序代码。架构一般会涉及到采用什么样的框架来加速和优化某部分问题的解决,而好的框架代码里合理使用了很多设计模式。  二、提炼设计模式的几个原则:  
发表于:2024-06-24 浏览:240 TAG:
【PHP】php中的compact()的用法
compact()参数有两种变量名的字符串形式数组的变量名变量名的字符串$city  = "San Francisco"; $state = "CA"; $event = "SIGGRAPH"; $location=["city",'state']; $result=compact('city','
发表于:2024-09-07 浏览:409 TAG: #php #compact
【PHP】RabbitMQ简介
1. RabbitMQ简介AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP 中消息的路由过程和 Java 开发者熟悉的 JMS 存在一些差别,AMQP 中增加了 Exchange 和 Binding 的角色。生产者把消息发布到
发表于:2024-06-11 浏览:249 TAG:
【PHP】支付宝第三方应用获取用户授权信息
支付宝服务商可创建第三方应用,一个第三方应用可绑定多个商家应用,商家应用绑定成功后会获取一个app_auth_token,授权令牌 app_auth_token 在没有重新授权、取消授权或刷新授权的情况下,永久有效。业务需要,要获取用户的user_id/open_id,1. 获取auth_code拼接授权urlhttps://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=APPID&scope=auth_base&am
发表于:2024-02-28 浏览:344 TAG: