他們終於即將到來 - 內置對枚舉的支持將在 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無涯私塾網