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の中にまとめておけます。