PHP 列舉 (Enums)
Enum(列舉)是 PHP 8.1 引入的一種特殊型別,用來定義一組固定的具名值。它比傳統的 const 常數更安全、更有表現力,且支援型別檢查。
基本列舉 (Pure Enums)
最簡單的列舉只包含名稱。
<?php
enum Status {
case Pending;
case Active;
case Completed;
case Archived;
}
function processStatus(Status $status) {
if ($status === Status::Active) {
// 處理活動中的狀態
}
}
processStatus(Status::Pending); // OK
// processStatus('Pending'); // TypeError: 必須是 Status 實例
?>
帶值列舉 (Backed Enums)
如果你需要將列舉與特定的值(如資料庫中的字串或整數)關聯,可以使用帶值列舉。帶值列舉必須指定型別(僅限 int 或 string)。
<?php
enum OrderStatus: string {
case Pending = 'P';
case Shipping = 'S';
case Delivered = 'D';
}
// 取得關聯的值
echo OrderStatus::Pending->value; // 輸出:P
// 從值建立列舉執行實例
$status = OrderStatus::from('S'); // 得到 OrderStatus::Shipping
$status = OrderStatus::tryFrom('X'); // 找不到時回傳 null
echo $status?->name; // 輸出:Shipping (名稱)
?>
列舉的方法
列舉可以包含方法,這讓它們比簡單的常數強大得多。
<?php
enum UserRole {
case Admin;
case Editor;
case Viewer;
public function getLabel(): string {
return match($this) {
self::Admin => '管理員',
self::Editor => '編輯者',
self::Viewer => '檢視者',
};
}
public function canEdit(): bool {
return $this === self::Admin || $this === self::Editor;
}
}
$role = UserRole::Admin;
echo $role->getLabel(); // 輸出:管理員
var_dump($role->canEdit()); // bool(true)
?>
列舉實作介面
列舉也可以實作介面。
<?php
interface HasLabel {
public function label(): string;
}
enum Priority implements HasLabel {
case Low;
case High;
public function label(): string {
return match($this) {
self::Low => '低優先度',
self::High => '高優先度',
};
}
}
?>
列舉常數
列舉內也可以定義常數。
<?php
enum Size {
case Small;
case Large;
public const DEFAULT = self::Small;
}
$size = Size::DEFAULT;
?>
取得所有列舉項
你可以使用 cases() 方法取得列舉中定義的所有項目陣列。
<?php
foreach (OrderStatus::cases() as $status) {
echo $status->name . " => " . $status->value . "\n";
}
?>
Enum vs Const
| 特性 | 常數 (const) | 列舉 (Enum) |
|---|---|---|
| 型別安全 | 弱,只是基本型別 | 強,擁有獨立型別 |
| 自動完成 | 一般 | 非常好 |
| 內建方法 | 無 | 有 (value, name, cases) |
| 自訂邏輯 | 無 | 可定義方法與實作介面 |
| PHP 版本 | 全部 | PHP 8.1+ |
什麼時候該用 Enum?
- 當有一組固定且已知的正體選項時(如:性別、訂單狀態、權限等級)。
- 當你需要確保傳入的參數絕對是該組選項之一時。
- 當你需要為這些選項添加額外邏輯(方法)時。