Menu
Coddy logo textTech

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;

出力:

active

Backed Enum は、値から Enum を作成するための from() メソッドと、無効な値に対してエラーをスローする代わりに null を返す tryFrom() を提供します:

<?php
$status = Status::from('active');      // Status::Active を返します
$invalid = Status::tryFrom('unknown'); // null を返します

Enumはメソッドを含むこともでき、関連するロジックをカプセル化するのに強力です。これらは型ヒントとシームレスに連携し、関数が有効な値のみを受け取ることを保証します。文字列が期待されるオプションと一致するかどうかをチェックする必要はもうありません。

challenge icon

チャレンジ

簡単

注文ステータスを型安全な方法で表現するために、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() メソッドを持つ
  • main.php — Order ファイルを読み込んでください。注文IDとステータス文字列(例:"shipped")の2つの入力を受け取ります。tryFrom() を使用して、入力された文字列を安全に OrderStatus Enum に変換してください。ステータスが有効な場合は、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" と出力する

?>
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン