Menu
Coddy logo textTech

列挙型(PHP 8.1)

CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 59/91。

PHP 8.1 より前は、ステータスや型のような固定された値の集合を表すには、class 定数やマジック文字列を使う必要がありました。どちらもエラーが発生しやすい方法です。列挙型(enumerations)を使うと、あらかじめ定義された特定の値だけを保持できる型を適切に定義できます。

enumキーワードを使用してenumをDefineします。

<?php
enum Status {
    case Pending;
    case Active;
    case Completed;
}

$status = Status::Active;
echo $status->name;

出力:

Active

列挙型には backed 値(文字列または整数値が each case に関連付けられたもの)も設定できます。これは、データベースや API に列挙型を保存する場合に便利です:

<?php
enum Status: string {
    case Pending = 'pending';
    case Active = 'active';
    case Completed = 'completed';
}

$status = Status::Active;
echo $status->value;

出力:

active

backed 列挙型には、その値から列挙型を作成する from() メソッドと、invalid な値に対してエラーをスローする代わりに null を返す tryFrom() が用意されています。

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

列挙型にはメソッドも含めることができるため、関連するロジックをカプセル化するうえで強力です。列挙型は型ヒントとシームレスに連携し、関数が有効な値だけを accept するようにできるので、文字列が期待される選択肢と一致するかを毎回確認する必要がなくなります。

challenge icon

チャレンジ

簡単

注文ステータスを型安全な方法で表現するために enum を使用する注文管理システムを構築しましょう。誤記や無効な値につながる可能性のある文字列に頼る代わりに、各ステータスをデータベースで扱いやすい値に対応付ける backed enum を作成します。

コードを3つのファイルに分けて整理します。

  • OrderStatus.php:4つの cases を持つ、文字列 backed enum の OrderStatus を Create します。
    • Pending'pending' に backed されます
    • Processing'processing' に backed されます
    • Shipped'shipped' に backed されます
    • Delivered'delivered' に backed されます
    各ステータスの human-readable な description を返す label() method を追加します。
    • Pending は "Awaiting confirmation" を返します
    • Processing は "Being prepared" を返します
    • Shipped は "On the way" を返します
    • Delivered は "Order complete" を返します
  • Order.php:enum を使用する Order class を Create します。OrderStatus ファイルを Include します。class は次のようにします。
    • constructor promotion を使用して、注文 ID(string)と OrderStatus を constructor で accept する
    • getInfo() method は "Order [id]: [status label]" を返す
    • getStatusValue() method はステータスの backed value を返す(データベースへの保存に便利です)
  • main.php:Order ファイルを Include します。2つの input、つまり注文 ID とステータス文字列("shipped" のような値)を受け取ります。tryFrom() を使用して、文字列 input を安全に OrderStatus enum に convert します。ステータスが有効な場合は、Order を Create して2行を print します。
    • getInfo() の結果
    • getStatusValue() の結果
    ステータス文字列が無効な場合は、"Invalid status" を print します。

この challenge は、enum がどのように型安全性を提供するかを示します。Order class は有効なステータスのみを accept でき、tryFrom() method によって、無効な値のリスクなしに user input を安全に処理できます。

自分で試してみよう

<?php

require_once 'Order.php';

// 入力を読み取る
$orderId = trim(fgets(STDIN));
$statusString = trim(fgets(STDIN));

// TODO: OrderStatus::tryFrom() を使用してステータス文字列を安全に列挙型に変換する
// tryFrom() は値が無効な場合に null を返す

// TODO: ステータスが有効な場合、Order を作成して以下を出力する:
// - getInfo() の結果
// - getStatusValue() の結果

// TODO: If the status is invalid, print "Invalid status"

?>
quiz icon腕試し

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

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

自分で練習してみよう: PHPオンラインコンパイラ