【PHP8.x】T_ENUM定数の使い方
T_ENUM定数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
T_ENUM定数は、PHP 8.1で導入された、PHPのキーワード「enum」を表すトークン定数です。PHP 8.1で新しく追加された列挙型(enum)の構文を、PHPエンジンが内部的に解析する際に使用されます。
「T_」で始まる定数は、PHPコードをより小さな要素(トークン)に分解し、その種類を識別するために用いられます。例えば、token_get_all()関数を使用してPHPソースコードを解析すると、コード内の「enum」というキーワードが、このT_ENUM定数として識別されたトークンとして取得されます。
この定数は、主にPHPの内部処理や、PHPコードの静的解析ツール、カスタムリンター、あるいはIDE(統合開発環境)のシンタックスハイライト機能といった、PHPコード自体を分析・処理するソフトウェアの開発において重要な役割を果たします。開発者が一般的なWebアプリケーションやスクリプトを作成する際に、直接このT_ENUM定数を使用する場面はほとんどありません。しかし、PHPの構文解析の仕組みや、特定キーワードの識別方法を理解する上で、重要な要素の一つです。PHP 8.1以降のバージョンで、enumキーワードを含むソースコードを正確に解析するために用いられます。
構文(syntax)
1<?php 2 3enum Status 4{ 5 case Active; 6 case Inactive; 7}
引数(parameters)
引数なし
引数はありません
戻り値(return)
戻り値なし
戻り値はありません
サンプルコード
PHP Enumで注文ステータスを安全に扱う
1<?php 2 3// PHP 8.1 以降で enum(列挙型)は利用可能です。 4// Enumは、事前に定義された有限の選択肢を安全かつ明確に表現するための機能です。 5// これは、マジックナンバーや文字列リテラルを避けてコードの可読性と保守性を向上させます。 6 7/** 8 * 注文の現在の状態を表すEnum。 9 * 各ケースは、その状態を識別するための文字列バッキング値を持っています。 10 * このバッキング値は、データベースへの保存やAPI通信などで利用できます。 11 */ 12enum OrderStatus: string 13{ 14 case PENDING = 'pending'; // 注文が保留中 15 case PROCESSING = 'processing'; // 注文が処理中 16 case SHIPPED = 'shipped'; // 注文が発送済み 17 case DELIVERED = 'delivered'; // 注文が配達済み 18 case CANCELLED = 'cancelled'; // 注文がキャンセル済み 19 20 /** 21 * Enumケースに基づいて、ユーザーフレンドリーな表示名を返します。 22 * このようにEnum内にビジネスロジックの一部を持たせることも可能です。 23 * 24 * @return string 25 */ 26 public function getDisplayName(): string 27 { 28 return match ($this) { 29 self::PENDING => '保留中', 30 self::PROCESSING => '処理中', 31 self::SHIPPED => '発送済み', 32 self::DELIVERED => '配達済み', 33 self::CANCELLED => 'キャンセル済み', 34 }; 35 } 36} 37 38/** 39 * 注文ステータスを受け取り、それに応じた処理とメッセージを出力する関数。 40 * 引数に `OrderStatus` 型ヒントを指定することで、この関数が特定のEnum型のみを受け入れることを保証します。 41 * 42 * @param OrderStatus $status 処理する注文ステータス 43 * @return void 44 */ 45function handleOrderStatus(OrderStatus $status): void 46{ 47 echo "現在の注文ステータス: " . $status->getDisplayName() . "\n"; 48 echo "システム内部値: " . $status->value . "\n"; // Enumのバッキング値にアクセス 49 50 // Enumのケースを直接比較することで、安全かつ明確な条件分岐が可能です。 51 if ($status === OrderStatus::DELIVERED) { 52 echo "この注文は顧客に正常に配達されました。\n"; 53 } elseif ($status === OrderStatus::CANCELLED) { 54 echo "この注文はキャンセル済みです。これ以上の処理は行われません。\n"; 55 } else { 56 echo "この注文は現在処理中です。次の段階に進みます。\n"; 57 } 58 echo "----------------------------------------\n"; 59} 60 61// Enumの利用例: 62echo "--- 注文ステータスの処理例 ---\n"; 63 64// 各Enumケースを関数に渡して処理を実行します。 65handleOrderStatus(OrderStatus::PENDING); 66handleOrderStatus(OrderStatus::PROCESSING); 67handleOrderStatus(OrderStatus::SHIPPED); 68handleOrderStatus(OrderStatus::DELIVERED); 69handleOrderStatus(OrderStatus::CANCELLED); 70 71// バッキング値からEnumインスタンスを生成する例 (PHP 8.1+): 72// OrderStatus::from() メソッドを使って、バッキング値からEnumインスタンスを取得できます。 73// 無効な値が渡された場合は ValueError がスローされます。 74// try { 75// $statusFromDb = OrderStatus::from('shipped'); 76// echo "--- データベースから取得したステータスの処理 ---\n"; 77// handleOrderStatus($statusFromDb); 78// } catch (\ValueError $e) { 79// echo "エラー: 無効なステータス値が指定されました: " . $e->getMessage() . "\n"; 80// }
PHP 8.1以降で利用可能なEnum(列挙型)は、事前に定義された有限の選択肢を安全かつ明確に表現するための機能です。これにより、マジックナンバーなどを排除し、コードの可読性と保守性が向上します。
サンプルコードでは、注文の状態を表すOrderStatusというEnumを定義しています。enum OrderStatus: stringと宣言することで、各Enumケース(例: PENDING)には文字列のバッキング値(例: 'pending')が関連付けられ、データベースへの保存やAPI通信などで活用できます。Enum内部にはgetDisplayName()のようなメソッドも定義可能で、match式を用いてEnumケースに応じたユーザーフレンドリーな表示名を返します。このメソッドは戻り値としてstringを返します。
handleOrderStatus関数は、引数$statusにOrderStatus型の型ヒントを指定しており、この関数がOrderStatusのインスタンスのみを受け入れることを保証します。関数内部では、$status->getDisplayName()で表示名を取得し、$status->valueでバッキング値にアクセスしています。また、if ($status === OrderStatus::DELIVERED)のように、Enumのケースを直接比較することで、安全で明瞭な条件分岐を記述できます。この関数は処理結果を出力するのみで、戻り値はvoid(何も返さない)です。
コメントアウトされている部分では、OrderStatus::from('shipped')のように、文字列のバッキング値から対応するEnumインスタンスを生成する方法が示されています。これにより、データベースから取得した値などを型安全にEnumとして扱うことができ、無効な値が渡された場合にはValueErrorがスローされるため、堅牢なエラーハンドリングも容易になります。
PHPのEnum(列挙型)は、バージョン8.1以降で利用可能です。Enumは、限定された選択肢を安全に表現し、コードの可読性と保守性を高めます。文字列などのバッキング値を持たせることができ、データベース保存やAPI連携に便利です。Enum内にメソッドを定義して関連ロジックを持たせたり、関数引数に型ヒントとして指定することで厳密な型チェックが可能です。Enumケースの比較は===で直接行えます。外部からの値からEnumインスタンスを生成するOrderStatus::from()メソッドは、無効な値に対してValueErrorをスローしますので、必ず例外処理を組み合わせて安全に利用してください。これにより、不正なデータによる予期せぬエラーを防ぎ、堅牢なコードになります。
PHP 8.1 Enumを文字列から変換する
1<?php 2 3// PHP 8.1以降で導入されたEnum(列挙型)を定義します。 4// string-backed enumは、各ケースに文字列値を関連付けることができます。 5// これにより、文字列からEnumケースへの変換が容易になります。 6enum UserStatus: string 7{ 8 case Active = 'active'; 9 case Inactive = 'inactive'; 10 case Pending = 'pending'; 11} 12 13/** 14 * 指定された文字列をUserStatus Enumのケースに変換します。 15 * 16 * @param string $statusString 変換するステータスの文字列。 17 * @return UserStatus|null 変換に成功した場合は対応するUserStatus Enumケース、 18 * 一致するケースがない場合はnullを返します。 19 */ 20function convertStringToUserStatus(string $statusString): ?UserStatus 21{ 22 // string-backedまたはint-backed Enumは`tryFrom`メソッドを提供します。 23 // このメソッドは、与えられた値に一致するEnumケースを返します。 24 // 一致するケースがなければnullを返すため、例外を処理する必要がありません。 25 return UserStatus::tryFrom($statusString); 26} 27 28// --- サンプル使用例 --- 29 30// 有効な文字列をEnumに変換する例 31$activeStatusString = 'active'; 32$activeStatus = convertStringToUserStatus($activeStatusString); 33 34if ($activeStatus !== null) { 35 echo "文字列 '{$activeStatusString}' は Enum ケース " . $activeStatus->name . " (値: " . $activeStatus->value . ") に変換されました。\n"; 36} else { 37 echo "文字列 '{$activeStatusString}' を UserStatus Enum に変換できませんでした。\n"; 38} 39 40// 別の有効な文字列をEnumに変換する例 41$pendingStatusString = 'pending'; 42$pendingStatus = convertStringToUserStatus($pendingStatusString); 43 44if ($pendingStatus !== null) { 45 echo "文字列 '{$pendingStatusString}' は Enum ケース " . $pendingStatus->name . " (値: " . $pendingStatus->value . ") に変換されました。\n"; 46} else { 47 echo "文字列 '{$pendingStatusString}' を UserStatus Enum に変換できませんでした。\n"; 48} 49 50// 無効な(一致しない)文字列をEnumに変換する例 51$unknownStatusString = 'suspended'; 52$unknownStatus = convertStringToUserStatus($unknownStatusString); 53 54if ($unknownStatus !== null) { 55 echo "文字列 '{$unknownStatusString}' は Enum ケース " . $unknownStatus->name . " (値: " . $unknownStatus->value . ") に変換されました。\n"; 56} else { 57 echo "文字列 '{$unknownStatusString}' を UserStatus Enum に変換できませんでした。\n"; 58}
PHP 8.1以降で導入されたEnum(列挙型)は、事前に定義された複数の選択肢の中から値を選択する際に利用される機能です。これにより、コードの可読性が向上し、入力ミスによるエラーを防ぐことができます。
このサンプルコードでは、ユーザーの状態を表すUserStatusというEnumを定義しています。UserStatus: stringのように定義することで、各Enumケースに文字列値を関連付ける「string-backed enum」として扱われ、文字列との相互変換が容易になります。
convertStringToUserStatus関数は、引数として受け取った文字列 $statusString をUserStatus Enumのケースに変換する役割を持ちます。この関数内部では、UserStatus::tryFrom($statusString)というメソッドが使用されています。tryFromメソッドは、与えられた文字列と一致するEnumケースがあればそれを返し、一致するケースがなければ安全にnullを返します。
本関数の戻り値は、変換に成功した場合は対応するUserStatus Enumケース、一致するケースがない場合はnullとなります。この仕組みにより、文字列からEnumへの変換処理を簡潔かつ安全に行うことができます。サンプルコードの実行結果から、有効な文字列はEnumに変換され、無効な文字列はnullとして扱われることを確認できます。
EnumはPHP 8.1以降で導入された機能であり、それより古いPHPバージョンでは動作しない点にご注意ください。サンプルコードのstring-backed enumは、各ケースに文字列値を関連付け、文字列からEnumケースへの型安全な変換を可能にします。特にtryFromメソッドは、与えられた文字列が定義されたEnumケースと一致しない場合にnullを返すため、必ず返り値のnullチェックを行い、後続処理でエラーが発生しないように注意しましょう。これにより、プログラムの予期せぬ停止を防ぎ、堅牢性を高めることができます。文字列によるマジックナンバーを避け、コードの可読性や保守性を向上させるためにEnumは非常に有効です。