こんにちは、Nakaです。
PHP 8.1 で Enum が導入されて以降、ステータス管理や種別管理を Enum で表現するコードはかなり一般的になりました。
一方で、実際のアプリケーションでは「この Enum をどう表示するか」という問題が必ず出てきます。管理画面・API・UI コンポーネントなど、**人間向けの意味(ラベル)**をどこで、どう管理するかは意外と悩ましいポイントです。
本記事では、Enum case に表示用ラベルを持たせる設計としてアトリビュートを用いた方法を紹介し、さらに PHPStan によってそのルールを機械的に保証する方法までを解説します。
以下はよくあるステータス管理です。
enum Status: int
{
case Draft = 0;
case Published = 1;
}
この Enum 自体はとても分かりやすく、ロジック上はこれで十分です。ただ、実際のアプリケーションではこういう要件が出てきます。
つまり、
Enum の case に「表示用の名前(ラベル)」を持たせたい
という要求です。この問題に対して、よく見かける実装はいくつかあります。
配列でマッピング:
const LABELS = [
Status::Draft->value => '下書き',
Status::Published->value => '公開中',
];
public function label(): string
{
return self::LABELS[$this->value];
}
switch で分岐:
public function label(): string
{
return match ($this) {
Status::Draft => '下書き',
Status::Published => '公開中',
};
}