列挙型(Enumerations)
PHP8.1で実装されたEnumの使い方を軽くご紹介します。
環境
$ php -v
PHP 8.1.1 (cli) (built: Dec 17 2021 23:49:52) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.1, Copyright (c) Zend Technologies
with Zend OPcache v8.1.1, Copyright (c), by Zend Technologies
使い方
<?php declare(strict_types=1);
enum AccountStatus
{
case Active;
case Inactive;
case Leave;
}
var_dump(AccountStatus::Active); // enum(AccountStatus::Active)
var_dump(AccountStatus::Active->name); // string(6) "Active"
var_dump(AccountStatus::cases());
// array(3) {
// [0]=>
// enum(AccountStatus::Active)
// [1]=>
// enum(AccountStatus::Inactive)
// [2]=>
// enum(AccountStatus::Leave)
// }
enum
と宣言して列挙型を宣言する。
case
を使って列挙していく。大文字も小文字も使える
AccountStatus::Active
とするとenumのインスタンスができる。
インスタンスの->name
プロパティへアクセスするとcaseの値を取得できる。
cases()
でenum値の一覧を取得できます。
<?php declare(strict_types=1);
enum AccountStatus: string
{
case ACTIVE = 'active';
case INACTIVE = 'inactive';
case LEAVE = 'leave';
/**
* @return string
*/
public function description(): string
{
return match($this) {
self::ACTIVE => '有効',
self::INACTIVE => '無効',
self::LEAVE => '退会済み',
};
}
}
var_dump(AccountStatus::ACTIVE); // enum(AccountStatus::ACTIVE)
var_dump(AccountStatus::ACTIVE->name); // string(6) "ACTIVE"
var_dump(AccountStatus::ACTIVE->value); // string(6) "active"
var_dump(AccountStatus::from('active')); // enum(AccountStatus::ACTIVE)
// var_dump(AccountStatus::from('undefined status')); // PHP Fatal error: Uncaught ValueError
var_dump(AccountStatus::tryFrom('active')); // enum(AccountStatus::ACTIVE)
var_dump(AccountStatus::tryFrom('undefined status')); // NULL
var_dump(AccountStatus::ACTIVE->description()); // string(6) "有効"
var_dump(AccountStatus::LEAVE->description()); // string(12) "退会済み"
var_dump(AccountStatus::cases());
// array(3) {
// [0]=>
// enum(AccountStatus::Active)
// [1]=>
// enum(AccountStatus::Inactive)
// [2]=>
// enum(AccountStatus::Leave)
// }
列挙型はスカラー値情報をデフォルトでは持ってませんが、スカラー値を持つcase(Backed Case)を定義できます。
intまたはstringのスカラー値をサポートしてます。
Backed Enumは内部的にBacked Enumインターフェースを実装しています。
from($value)
や tryFrom($value)
でスカラー値からEnumのcaseを返します。
<?php declare(strict_types=1);
final class Account
{
public function __construct(
private AccountStatus $accountStatus,
) {
}
}
$account = new Account(AccountStatus::Active);
$account = new Account('undefined status');
// Fatal error: Uncaught TypeError: Account::__construct(): ...
他のクラスのコンストラクタで列挙型を型宣言して受け取れる。
未定義の値を渡すと型エラーが発生するので不正な値が入ることを防いでくれる。安心。
Enumとクラスの違い
- 状態を持つことが禁止
- コンストラクタやデストラクタは禁止
- 継承は禁止
- プロパティを持つことは禁止
- public, private, protected メソッド は利用可能
- public, private, protected な static メソッド は利用可能
- public, private, protected な定数 は利用可能
- インターフェースの実装 は利用可能
- マジックメソッド
__call
,__callStatic
,__invoke
は利用可能。これ以外は禁止 - マジック定数
__CLASS__
と__FUNCTION__
は利用可能。これ以外は禁止
感想
思ったより扱いやすそう!早く実務で使ってみたい。
ただ、インターフェース使ったEnumはいまいち実務で使うイメージができなかった。
今まではBenSampo/laravel-enumパッケージを使ってたけど乗り換えて良さそう。