2
1

【PHP】Enumでの検証を簡単にする

Last updated at Posted at 2024-07-19

PHPのEnumでの検証

以下のようなEnumがあるとしたとき

enum Test: string
{
    case Test1 = 'test1';
    case Test2 = 'test2';
    case Test3 = 'test3';
}

検証の際いちいち

if ($test === Test::Test1) {}

みたいなことを書くと可読性が悪くなる気がしたので

以下のようなトレイトを用意して

trait EnumIsTrait {
    public static function tryFromName(string $name)
    {
        foreach (self::cases() as $case) {
            if ($case->name === $name) {
                return $case;
            }
        }
        return null;
    }
    

    public function is(string $name)
    {
        return $this === self::tryFromName($name);
    }
    

    public function __call($calledName, $args)
    {
        preg_match('/^is([a-zA-Z0-9]+)$/', $calledName, $matches);
        $caseName = $matches[1] ?? false;
        if ($caseName) {
            return $this->is($caseName);
        }

        throw new \Exception();
    }
}

先ほどのEnumに実装すると

enum Test: string
{
    use EnumIsTrait;
    case Test1 = 'test1';
    case Test2 = 'test2';
    case Test3 = 'test3';
}
if ($test->isTest1()) { }

のような形で検証ができると思います。
関数の実態はないので、@method などを定義しておくと良いと思います。

確認用コード

<?php

enum Test: string
{
    use IsEnumTrait;
    
    case Test1 = 'test1';
    case Test2 = 'test2';
    case Test3 = 'test3';
}

trait IsEnumTrait {

    /**
     * Enumの name から Enumを取得
     */
    public static function tryFromName(string $name)
    {
        foreach (self::cases() as $case) {
            if ($case->name === $name) {
                return $case;
            }
        }
        return null;
    }
    

    /**
     * 現在のEnumが name のEnumかどうか検証
     */
    public function is(string $name)
    {
        return $this === self::tryFromName($name);
    }
    

    public function __call($calledName, $args)
    {
        preg_match('/^is([a-zA-Z0-9]+)$/', $calledName, $matches);
        $caseName = $matches[1] ?? false;
        if ($caseName) {
            return $this->is($caseName);
        }

        throw new \Exception();
    }
}

var_dump(Test::Test1->isTest1());
var_dump(Test::Test2->isTest1());

// outputs
// bool(true)
// bool(false)

laravelのモデルのプロパティにEnumをセットして判定する際は
$casts = [];
でEnumへの変換を設定していると
$this->xxxx->is〇〇();
で判定できるので一行あたりが短く書けるかなと思いました。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1