PHP 8.1: 列挙型

in Vlog

(CJP) それらはついに登場します — enum のビルトインサポートが PHP 8.1 に追加されます! 期限が過ぎていると考える人もいるかもしれませんが、私が文句を言うのは聞こえません。 彼らがそれを成し遂げたことをうれしく思います! この投稿では、新しく追加された機能について詳しく説明します。 PHP のこの種の変更や新機能に関する最新情報を入手したい場合は、必ず私のニュースレターを購読してください。

いつものように、私の PHP 機能の投稿と同様に、enum がどのように見えるかについての高レベルの概要から始めます。

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();

静的メソッドも許可されています。

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

# 列挙値 — 別名「Backed enums」

列挙値は内部的にオブジェクトによって表されますが、必要に応じてそれらに値を割り当てることができます。 これは、たとえば次の場合に役立ちます。 それらをデータベースにシリアライズします。

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;

型付き列挙型の専門用語は、より単純な値によって「裏付けられている」ため、「裏付けられた列挙型」と呼ばれます。 列挙値を割り当てる場合は、すべてのケースに値が必要です。 それらを混ぜて一致させることはできません。 「バックアップ」されていない列挙型は「純粋な列挙型」と呼ばれます。

# インターフェイス付きのバッキングされた列挙型

バッキングされた列挙型とインターフェイスを組み合わせる場合、列挙型は列挙型名の直後、 implements キーワード。

enum Status: string implements HasColor

case DRAFT = ‘draft’;
case PUBLISHED = ‘published’;
case ARCHIVED = ‘archived’;

# 裏づけされた列挙型のシリアライズ

列挙型のケースに値を代入する場合、それらをシリアライズおよびデシリアライズする方法が必要になるでしょう。 それらをシリアル化するということは、列挙型の値にアクセスする方法が必要であることを意味します。 これは、読み取り専用のパブリック プロパティで行われます。

$value = Status::PUBLISHED->value;

値から列挙型を復元するには、 Enum::from:

$status = Status::from(2);

もあります tryFrom それが返す null 不明な値が渡された場合。 使用する場合 from 例外があるでしょう。

$status = Status::from(‘unknown’);
$status = Status::tryFrom(‘unknown’);

組み込みの serialize と unserialize 列挙型の関数。 さらに、使用できます json_encode 裏付けられた列挙型と組み合わせると、その結果は列挙型の値になります。 この動作は、実装することでオーバーライドできます JsonSerializable.

# 列挙値の一覧表示

静的を使用できます Enum::cases() 列挙型内で使用可能なすべてのケースのリストを取得するメソッド:

Status::cases();

この配列には実際の列挙オブジェクトが含まれていることに注意してください。

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

# 列挙型はオブジェクトです

列挙型の値はオブジェクトとして表されると既に述べましたが、実際にはこれらはシングルトン オブジェクトです。 つまり、次のように比較できます。

$statusA = Status::PENDING;
$statusB = Status::PENDING;
$statusC = Status::ARCHIVED;

$statusA === $statusB;
$statusA === $statusC;
$statusC instanceof Status;

# 配列キーとしての列挙

enums 値は実際にはオブジェクトであるため、現在、それらを配列キーとして使用することはできません。 以下はエラーになります。

$list = [
Status::DRAFT => ‘draft’,

];

この動作を変更する RFC がありますが、まだ投票されていません。

これは、列挙型のみをキーとして使用できることを意味します SplObjectStorage と WeakMaps.

# 特徴

列挙型は、クラスと同じように特性を使用できますが、いくつかの制限があります。 組み込みの列挙型メソッドをオーバーライドすることは許可されておらず、それらにクラス プロパティを含めることはできません — これらは列挙型では禁止されています。

# リフレクションと属性

予想どおり、列挙型を処理するために追加されたいくつかのリフレクション クラスがあります。 ReflectionEnum、 ReflectionEnumUnitCase と ReflectionEnumBackedCase. 新作もあります enum_exists その名前が示すとおりの機能です。

通常のクラスやプロパティと同様に、列挙型とそのケースには属性を使用して注釈を付けることができます。 ご了承ください TARGET_CLASS フィルターには列挙型も含まれます。

最後にもう 1 つ: enum には読み取り専用のプロパティもあります。 $enum->nameRFC で言及されているのは実装の詳細であり、おそらくデバッグ目的でのみ使用する必要があります。 それでも言及する価値はあります。

tpyoに気づきましたか? PR を送信して修正することができます。 このブログの最新情報を知りたい場合は、私をフォローしてください。 ツイッター または私のニュースレターを購読してください:

列挙型について言えることはこれだけです。PHP 8.1 がリリースされたらすぐに列挙型を使用することを楽しみにしています。また、自分のユーザーランドの実装を廃止することも楽しみにしています。

関連記事

前の投稿
スカンクは冬にどこへ行くの?
次の投稿
コップ一杯の水の中の嵐