Enum

列挙型

「enum」(列挙型または列挙子型)は、プログラムで特定の値のセットを定義し、その値の中から1つを選択するためのデータ型。

役割

列挙型は、関連する定数をグループ化し、可読性を向上させ、プログラムの誤りを減らすのに役立つ。プログラム内で使用可能な値のリストを列挙したり、定義したりする際に使用される。
enumはクラスのように扱えるが、インスタンス化できない。
enumのインスタンス化は、enum内部で一度だけ行うので、enumの各インスタンスはプログラム全体の中でひとつであることが保証(昔Javaの現場で教わった。。PHPも同じ?)。
この特徴によって、enumが定数として機能します。

その他特徴

可能

public, private, protected メソッド は利用可能
public, private, protected な static メソッド は利用可能
public, private, protected な定数 は利用可能
インターフェースの実装 は利用可能

不可能

コンストラクタやデストラクタは禁止
継承は禁止
プロパティを持つことは禁止

列挙型の例

列挙型の例(PHP 8.1以降):
enumキーワードに列挙名が続き、caseキーワードで各列挙を定義する。

<?php
enum Day {
    case Monday;
    case Tuesday;
    case Wednesday;
    case Thursday;
    case Friday;
    case Saturday;
    case Sunday;
}

intまたはstringのスカラー値を持つcaseも定義(Backed Enum)できる。
同じスカラー値を定義してもエラーにはならない。

<?php
enum Day {
    case Monday = 1;
    case Tuesday = 2;
    case Wednesday = 3;
    case Thursday = 4;
    case Friday = 5;
    case Saturday = 6;
    case Sunday = 7;
}

実行例

enum Day {
    case Monday = 1;
    case Tuesday = 2;
    case Wednesday = 3;
    case Thursday = 4;
    case Friday = 5;
    case Saturday = 6;
    case Sunday = 7;
}

foreach (Day::cases() as $key => $val) {
  var_dump($key,  $val)
}

string(6) "Monday"
int(1)
string(7) "Tuesday"
int(2)
string(9) "Wednesday"
int(3)
string(8) "Thursday"
int(4)
string(6) "Friday"
int(5)
string(8) "Saturday"
int(6)
string(6) "Sunday"
int(7)

使用できるメソッド

Case

  • cases()
    Enumに定義されている全てのcaseを要素に持つ配列を返すメソッドです。配列の要素は宣言された順に含まれる。

Backed Case

ともにスカラー値からBacked Caseを返すメソッド。

  • from(スカラー値)
    Backed Caseがない場合、fromメソッドはValueErrorがスローされる
  • tryFrom(スカラー値)
    Backed Caseがない場合、tryFromメソッドはNullを返す。

メリット

  • 型安全性(Type Safety): Enum型の変数にはEnumで定義された値しか代入できないことにより、不正な値がプログラムに渡ることを防ぐことができる。
  • 可読性と保守性: Enumを使用することで、コードの可読性が向上します。値が何を表しているのかが明確になり、コードの意図が理解しやすい。また、Enumケースの追加や変更が簡単で、コードの保守性が向上する。

使い所

カテゴリやステータス

バリデーション

<?php
namespace App\Enums;

enum ServerStatus: string {
    case ACTIVE = 'active';
    case INACTIVE = 'inactive';
}
<?php
namespace App\Http\Requests;

use App\Enums\ServerStatus;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rules\Enum;

class ServerRequest extends FormRequest
{
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules()
    {
        return [
            'status' => [new Enum(ServerStatus::class)],
        ];
    }
}
  • リクエストパラメータの Enum case 化
    バリデーションを通過しても、リクエストパラメータは文字列のままなので、
    文字列から Enum の case に変換するために、Enum::from()を使う 。

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Enums\ServerStatus;
use App\Http\Requests\ServerRequest;

class ServerController extends Controller
{
    /**
     * Store a newly created resource in storage.
     *
     * @param  \App\Http\Requests\ServerRequest  $request
     * @return \Illuminate\Http\Response
     */
    public function store(ServerRequest $request)
    {
        $validated = $request->validated();
        $status = ServerStatus::from($validated['status']);
        // ...
    }
}

補足その他の使い所
・ワークフローなど機能でステータス遷移の場面で便利メリット
・インスタンス比較
シングルトンだからインスタンス同士の比較できる。
クラスはプロパティまで見ないと比較できない。
・クエリビルダでいい感じに使えるTSの場合
JSコンパイル時のオーバーヘッドが危惧

コメント

タイトルとURLをコピーしました