Enum (PHP 8.1)
CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 59/91。
PHP 8.1 以前は、ステータスや型のような固定された値のセットを表現するには、クラス定数やマジック文字列を使用することを意味していました。これらはどちらもエラーが発生しやすいアプローチです。Enums(列挙型)は、特定のあらかじめ定義された値のみを保持できる型を定義するための適切な方法を提供します。
enumキーワードを使用して列挙型を定義します:
<?php
enum Status {
case Pending;
case Active;
case Completed;
}
$status = Status::Active;
echo $status->name;
出力:
Active列挙型(Enums)は、各ケースに関連付けられた文字列または整数の値であるBacked Valuesを持つこともできます。これは、列挙型をデータベースやAPIに保存する際に便利です:
<?php
enum Status: string {
case Pending = 'pending';
case Active = 'active';
case Completed = 'completed';
}
$status = Status::Active;
echo $status->value;
出力:
activeBacked Enum は、値から Enum を作成するための from() メソッドと、無効な値に対してエラーをスローする代わりに null を返す tryFrom() を提供します:
<?php
$status = Status::from('active'); // Status::Active を返します
$invalid = Status::tryFrom('unknown'); // null を返します
Enumはメソッドを含むこともでき、関連するロジックをカプセル化するのに強力です。これらは型ヒントとシームレスに連携し、関数が有効な値のみを受け取ることを保証します。文字列が期待されるオプションと一致するかどうかをチェックする必要はもうありません。
チャレンジ
簡単注文ステータスを型安全な方法で表現するために、Enum(列挙型)を使用した注文管理システムを構築しましょう。スペルミスや無効な値の可能性がある文字列に頼る代わりに、各ステータスをデータベースに適した値にマッピングする Backed Enum を作成します。
コードは以下の3つのファイルに分けて構成します:
OrderStatus.php— 以下の4つのケースを持つ、OrderStatusという名前の文字列ベースの Backed Enum を作成してください:Pending:値は'pending'Processing:値は'processing'Shipped:値は'shipped'Delivered:値は'delivered'
label()メソッドを追加してください:- Pending は
"Awaiting confirmation"を返します - Processing は
"Being prepared"を返します - Shipped は
"On the way"を返します - Delivered は
"Order complete"を返します
Order.php— この Enum を使用するOrderクラスを作成してください。OrderStatus ファイルを読み込んでください。このクラスは以下の要件を満たす必要があります:- コンストラクタのプロパティプロモーションを使用して、注文ID(文字列)と
OrderStatusを受け取る "Order [id]: [status label]"を返すgetInfo()メソッドを持つ- ステータスの Backed Value(データベース保存に便利です)を返す
getStatusValue()メソッドを持つ
- コンストラクタのプロパティプロモーションを使用して、注文ID(文字列)と
main.php— Order ファイルを読み込んでください。注文IDとステータス文字列(例:"shipped")の2つの入力を受け取ります。tryFrom()を使用して、入力された文字列を安全にOrderStatusEnum に変換してください。ステータスが有効な場合は、Orderを作成し、以下の2行を出力してください:getInfo()の結果getStatusValue()の結果
"Invalid status"と出力してください。
このチャレンジでは、Enum がどのように型安全を提供するかを学びます。Order クラスは有効なステータスのみを受け入れることができ、tryFrom() メソッドを使用することで、無効な値のリスクを負うことなくユーザー入力を安全に処理できます。
チートシート
Enum(列挙型)は、固定された値のセットを定義するための型安全な方法を提供します。enumキーワードを使用してEnumを定義します:
<?php
enum Status {
case Pending;
case Active;
case Completed;
}
$status = Status::Active;
echo $status->name; // 出力: Active
Backed Enum(値付き列挙型)は、各ケースに文字列または整数の値を関連付けます:
<?php
enum Status: string {
case Pending = 'pending';
case Active = 'active';
case Completed = 'completed';
}
$status = Status::Active;
echo $status->value; // 出力: active
from()を使用して値からEnumを作成するか、無効な値に対してnullを返すtryFrom()を使用します:
<?php
$status = Status::from('active'); // Status::Active を返す
$invalid = Status::tryFrom('unknown'); // null を返す
Enumには、関連するロジックをカプセル化するためのメソッドを含めることができます:
<?php
enum Status: string {
case Pending = 'pending';
case Active = 'active';
public function label(): string {
return match($this) {
self::Pending => 'Awaiting',
self::Active => 'In Progress',
};
}
}
自分で試してみよう
<?php
require_once 'Order.php';
// 入力を読み込む
$orderId = trim(fgets(STDIN));
$statusString = trim(fgets(STDIN));
// TODO: OrderStatus::tryFrom() を使用して、ステータス文字列を安全に列挙型(enum)に変換する
// tryFrom() は値が無効な場合に null を返す
// TODO: ステータスが有効な場合は、Order を作成して以下を出力する:
// - getInfo() の結果
// - getStatusValue() の結果
// TODO: ステータスが無効な場合は、"Invalid status" と出力する
?>このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
10オブジェクト指向の高度な概念
コンポジション vs 継承依存性の注入 (Dependency Injection)匿名クラスEnum (PHP 8.1)ファイバー (PHP 8.1)オブジェクトのクローン徹底解説ジェネレータとイテレータ