簡單介紹 PHP 8.1 的列舉 (Enumerations)

PHP 8.1 在前陣子正式推出!加入不少新功能,其中包含最多人期待的列舉 (Enumerations)。

列舉可以用來定義一系列的常數設定值,避免在開發時使用無效的設定值。

簡單的 enum 設定如下。

// 沒有回退 (non-backed) 的 enum 不能設定初始值
enum UserRole {
    case ADMIN;
    case USER;
    case GUEST;
}

// 有回退的 enum 一定要設定初始值
enum UserName: string {
    case ADMIN = 'admin';
    case USER = 'user';
    case GUEST = 'guest';
}

// 有回退的 enum 只能設定 int 與 string
enum UserNumber: int {
    case ADMIN = 1;
    case USER = 2;
    case GUEST = 3;
}

enum 可以看做是物件,有預設的屬性 namevalue

// enum 物件有預設的屬性 name 與 value
var_dump(UserName::ADMIN->name); // ADMIN
var_dump(UserName::ADMIN->value); // admin

此外也有預設的靜態方法 from(),此方法可以依據 value 回推 enum 中的 case,如果找不到就會拋出錯誤。
如果不想讓錯誤停止程式執行,可以使用 tryFrom()

// enum 物件有預設的方法
var_dump(UserName::from('admin')); // enum(Enum\UserName::ADMIN)
var_dump(UserName::from('hello')); // throw error !!!
var_dump(UserName::tryFrom('hello')); // null

enum 內部還可以設定方法。

enum UserRole {
    case ADMIN;
    case USER;
    case GUEST;

    // enum 內部可以設定 method
    public function content(): string
    {
        return match($this) {
            self::ADMIN => 'admin',
            self::USER => 'user',
            self::GUEST => 'guest',
        };
    }
}

var_dump(UserRole::ADMIN->content()); // admin

當一個 class 的初始參數被設定為 enum 時,就只能傳入 enum,以此來限制值的範圍。

class User
{
    public function __construct(
        public UserName $userName,
    ) {}
}

$user = new User('admin'); // throw error !!!
$user = new User(UserName::ADMIN);

var_dump($user->userName); // enum(Enum\UserName::ADMIN)

參考資料


PHP: Enumerations overview - Manual

sharkHead
written by
sharkHead
後端工程師, PHP 基金會每月 10 刀贊助人
稍微擅長 PHP、Python 與 Google 搜尋,偶爾寫寫 TypeScript