PHPのenum(列挙型)で「文字列べた書き」をやめる

enum(列挙型)はPHP 8.1で追加された機能で、取りうる値を型として定義する仕組みです。文字列べた書きによるタイプミスを防ぎ、決まった選択肢を型安全に扱えます。

ステータスを'draft''publish'のような文字列で持ち回っていると、タイプミスに気づけません。PHP 8.1のenumを使うと、取りうる値を型で縛れます。

基本形

enum Status: string
{
    case Draft = 'draft';
    case Publish = 'publish';
    case Future = 'future';
}

function setStatus(Status $status): void { /* ... */ }

setStatus(Status::Draft);       // OK
setStatus('draft');             // TypeError: 文字列は渡せない

引数の型をStatusにしておけば、想定外の文字列が混入する余地がなくなります。IDEの補完も効きます。

値との相互変換

: string付きのenum(backed enum)なら、値との変換ができます。DBに保存された文字列から復元するときに使います。

$s = Status::from('publish');       // Status::Publish
$s = Status::tryFrom('unknown');    // null(fromは例外)
echo Status::Draft->value;          // 'draft'

DBからの値は信用できないので、例外を投げるfromより、nullで受けられるtryFromのほうが扱いやすい場面が多いです。

メソッドも持てる

enum Status: string
{
    case Draft = 'draft';
    case Publish = 'publish';

    public function label(): string
    {
        return match($this) {
            Status::Draft => '下書き',
            Status::Publish => '公開',
        };
    }
}

まとめ

「決まった選択肢しか取らない値」はenumの出番です。文字列べた書きより安全で、表示名などの付随ロジックもenumにまとめられます。定数クラスで代用していた人は、一度置き換えてみると手放せなくなると思います。

よくある質問

Q. fromとtryFromはどちらを使えばいいですか。
A. 存在しない値でfromは例外を投げ、tryFromはnullを返します。DBなど信用できない入力から復元するときは、nullで受けられるtryFromが扱いやすいです。

Q. enumにメソッドを持たせられますか。
A. 持たせられます。表示名を返すlabel()のような付随ロジックを、enumの中にまとめておけます。

類似投稿

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です