(archtechx/enums) Enum Helper の使い方 対話篇



[PHP Enum（列挙型）基礎 対話編](https://qiita.com/KeijiYONEDA/items/b300048b1b45e7d68b27)の続きです

*PHPとLaravelを利用した血液型占いアプリを作成することになった"後輩エンジニアくん"。*
*ちょっと前に登場した、PHPのenum（列挙型）型を使おうとしたが、
正直そのまま使うにはキツいところもあり、いい感じのヘルパーがないか探していると...*

後「"Laravel Enum Helper"でググったら、早速使えそうなのをみつけましたよ。[Laravel News](https://laravel-news.com/enum-helpers-for-php)で」
先「どんなん？」

[archtechx/enums: Helpers for making PHP enums more lovable.](https://github.com/archtechx/enums)

先「どうやって使うの？」
後「traitとして使います」
先「trait..そういえば、enumは継承使えないんだっけね」

# Pure Enumでfromが使えない件への改善

後「まずはPure Enumだとconstant()とか使わないと逆引きできなかった所を、fromで逆引きできるようになります」

```php
use ArchTech\Enums\From;

enum BloodType
{
    use From;

    case A;
    case B;
    case AB;
    case O;
}

BloodType::from('B');
BloodType::tryFrom('B');
```

先「いいじゃない」
後「あと、Backed Enumに対しても、fromNameでnameからenumに変換できますよ」

```php
use ArchTech\Enums\From;

enum BloodType :string
{
    use From;
    case A = 'A型';
    case B = 'B型';
    case AB = 'AB型🍤';
    case O = 'O型';
}

BloodType::fromName('B型');
BloodType::tryFromName('B型');
```

先「かゆい所に手が届くね」

## Backed Enumをoptions的な連想配列にするのがキツイ件への改善

先「選択肢（オプション）として配列に変換したいときに、キツめな記述になる件は？」

後「そのまんま`Options`というtraitがあります。」

```php
use ArchTech\Enums\Options;

enum BloodType :string
{
    use Options;

    case A = 'A型';
    case B = 'B型';
    case AB = 'AB型🍤';
    case O = 'O型';
}

BloodType::options(); // ["A" => "A型", "B" => "B型",...,]

```

後「`Names`, `Values`ってのもありますよ。」


```php
use ArchTech\Enums\Names;

enum BloodType :string
{
    use Names;
    case A = 'A型';
    case B = 'B型';
    case AB = 'AB型🍤';
    case O = 'O型';
}

BloodType::names(); // ["A", "B",...,]
```

```php
use ArchTech\Enums\Values;

enum BloodType :string
{
    use Names;
    case A = 'A型';
    case B = 'B型';
    case AB = 'AB型🍤';
    case O = 'O型';
}

BloodType::values(); // ["A型", "B型",...,]
```
先「かゆいところにてがとどくね」


## caseから勝手に文字列に変換されるようにはならないが、かなり楽に

後「毎回 `->value`って書くのはしんどいじゃないですか。」
先「うん」
後「これについては、caseを関数として【実行】できる形にする事で、記述を省略できるtraitがあるんですよ。」


```php
use ArchTech\Enums\InvokableCases;

enum TaskStatus: int
{
    use InvokableCases;

    case INCOMPLETE = 0;
    case COMPLETED = 1;
    case CANCELED = 2;
}

TaskStatus::INCOMPLETE(); // 0
TaskStatus::COMPLETED(); // 1
TaskStatus::CANCELED(); // 2

```

後「Pure Enumなら、nameを取ってくる。これは楽ですね」

```
enum Role
{
    use InvokableCases;

    case ADMINISTRATOR;
    case SUBSCRIBER;
    case GUEST;
}

Role::ADMINISTRATOR(); // 'ADMINISTRATOR'
Role::SUBSCRIBER(); // 'SUBSCRIBER'
Role::GUEST(); // 'GUEST'
```

先「かゆうまいね。」


## プロパティ増やせない件(審議中)

先「各caseは、nameとvalueしかプロパティｗ持てない、ってのもあったよね」
後「一応、プロパティ的なものを簡単に増やす機能も...ありますよ...」

```php
use ArchTech\Enums\Metadata;
use ArchTech\Enums\Meta\Meta;
use App\Enums\MetaProperties\{Description, Color};

#[Meta(Description::class, Color::class)]
enum TaskStatus: int
{
    use Metadata;

    #[Description('Incomplete Task')] #[Color('red')]
    case INCOMPLETE = 0;

    #[Description('Completed Task')] #[Color('green')]
    case COMPLETED = 1;

    #[Description('Canceled Task')] #[Color('gray')]
    case CANCELED = 2;
}

TaskStatus::INCOMPLETE->description(); // 'Incomplete Task'
TaskStatus::COMPLETED->color(); // 'green'
```

先「ちょっとまって何これは」

後「PHPの[Attributes](https://wiki.php.net/rfc/attributes_v2)ってのを使ってるらしいです」
先「プロパティではなく、あくまで関数の追加なんやね。]
先「なんか黒魔術感があるなあ。おれ、Javaのアノテーションとかも苦手やったから..」



# そして

とりあえず、`archtechx/enums`を使えばEnum使っててもそこまでキツくなさそう！ということになり、
一旦知見を貯めるためにも、enumを導入してみることになりましたとさ。

おしまい。