本文系翻譯,原文網址:https://stitcher.io/blog/php-enums
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
以上是PHP8.1新特性大講解之Enums枚舉的詳細內容。更多資訊請關注PHP中文網其他相關文章!