laravel-enumの使い方を都度調べてしまうのでまとめた


[Laravel Advent Calendar 2021](https://qiita.com/advent-calendar/2021/laravel) 9日目の投稿です。

## 概要
laravel-enumって便利ですよね。（PHPでも使えるようになったのは今回触れない）
便利なものって使い方がいろいろあるから調べますよね。
調べる→試す、これを繰り返していたらどんなに時間があっても足りません。

この記事はEnumの使い方について書いたものです。
僕と同じように時間を浪費してしまっているかたへ届くと嬉しいです。

## この記事でわかること
laravel-enumの使い方について
調べる時間を減らして効率アップ
この記事がlaravel-enumの虎の巻でありたい←願望

## 解決したい課題
laravel-enumを使おう！
え〜っとどう使うんだっけ？

laravel-enumというのを知ってから毎度使う時に
様々な記事から使い方を調べて試してを繰り返してきました。

今回はそんな「毎回調べる」ということをこの記事でなくしたいと思います。
## 課題を解決する技術、手法
laravel-enumのインストール方法は[こちら](https://github.com/BenSampo/laravel-enum#installation)
公式の内容を自分なりの解釈でまとめていきます。
enumを使って`UserType`クラスが作成されている前提です。

``` php
<?php

namespace App\Enums;

use BenSampo\Enum\Enum;

final class UserType extends Enum
{
    const Administrator = 0;
    const Moderator = 1;
    const Subscriber = 2;
    const SuperAdministrator = 3;
}
```
例えば下記のように使用できる

``` php
UserType::Administrator // 0が返ってくる
```

他にも様々な使い方がある

`getKyes(mixed $keys = null): array`
全てのキーの配列またはカスタムセットを返す

``` php
UserType::getKeys();
// ['Administrator', 'Moderator', 'Subscriber', 'SuperAdministrator']が返ってくる

UserType::getKeys(UserType::Administrator);
// ['Administrator']が返ってくる

UserType::getKeys(UserType::Administrator, UserType::Moderator);
// ['Administrator', 'Moderator']が返ってくる

UserType::getKeys([UserType::Administrator, UserType::Moderator]);
// ['Administrator', 'Moderator']が返ってくる

```

`getValues(mixed $keys = null): array`
全ての配列または値のカスタムセットを返す.

``` php
UserType::getValues();
// [0, 1, 2, 3]が返ってくる

UserType::getValues('Administrator');
// [0]が返ってくる

UserType::getValues('Administrator', 'Moderator');
// [0, 1]が返ってくる

UserType::getValues(['Administrator', 'Moderator']);
// [0, 1]が返ってくる
```

`getKey(mixed $value): string`
指定された列挙値のキーを返す。

``` php
UserType::getKey(1);
// 'Moderator'が返ってくる

UserType::getKey(UserType::Moderator);
// 'Moderator'が返ってくる
```

`hasKey(string $key): bool`
列挙型に特定のキーが含まれているかどうかを確認する。

``` php
UserType::hasKey('Moderator');
// 'True'を返す
```

`hasValue(mixed $value, bool $strict = true): bool`
列挙型に指定された値が含まれているかどうかを確認する。

``` php
UserType::hasValue(1);
// 'True'を返す

// 厳密な型チェックを無効にできる
UserType::hasValue('1');
// 'False'を返す
UserType::hasValue('1', false);
// 'True'を返す
```

`getDescription(mixed $value): string`
列挙値の文の場合のキーを返します。
getDescriptionメソッドをオーバーライドして、カスタムの説明を返すことができる。

``` php
UserType::getDescription(3);
// 'Super administrator'を返す
UserType::getDescription(UserType::SuperAdministrator);
// 'Super administrator'を返す
```

`getRandomKey(): string`
列挙型からランダムキーを返す。 Factoryで使用すると便利です。

``` php
UserType::getRandomKey();
// 'Administrator', 'Moderator', 'Subscriber' または 'SuperAdministrator'を返す
```

`getRandomValue(): mixed`
列挙型からランダムな値を返します。Factoryで使用すると便利です。

``` php
UserType::getRandomValue();
// 0, 1, 2 または 3 を返す
```

`getRandomInstance(): mixed`
列挙型のランダムインスタンスを返す。Factoryで使用すると便利です。

``` php
UserType::getRandomInstance();
// ランダムな値を持つUserTypeのインスタンスを返す
```

`asArray(): array`
列挙型キーと値のペアを連想配列として返す。

``` php
UserType::asArray();
// ['Administrator' => 0, 'Moderator' => 1, 'Subscriber' => 2, 'SuperAdministrator' => 3]を返す
```

`asSelectArray(): array`
select as value => descriptionで使用する列挙型を返す。

``` php
UserType::asSelectArray();
// [0 => 'Administrator', 1 => 'Moderator', 2 => 'Subscriber', 3 => 'Super administrator']を返す
```

`fromValue(mixed $enumValue): Enum`
呼び出された列挙型のインスタンスを返しす。

``` php
UserType::fromValue(UserType::Administrator);
// UserType::Administratorに設定されたEnumのインスタンスを返す
```

`getInstances(): array`
定数名でキー設定された、呼び出された列挙型のすべての可能なインスタンスの配列を返す。

``` php
var_dump(UserType::getInstances());

array(4) {
  'Administrator' =>
  class BenSampo\Enum\Tests\Enums\UserType#415 (3) {
    public $key =>
    string(13) "Administrator"
    public $value =>
    int(0)
    public $description =>
    string(13) "Administrator"
  }
  'Moderator' =>
  class BenSampo\Enum\Tests\Enums\UserType#396 (3) {
    public $key =>
    string(9) "Moderator"
    public $value =>
    int(1)
    public $description =>
    string(9) "Moderator"
  }
  'Subscriber' =>
  class BenSampo\Enum\Tests\Enums\UserType#393 (3) {
    public $key =>
    string(10) "Subscriber"
    public $value =>
    int(2)
    public $description =>
    string(10) "Subscriber"
  }
  'SuperAdministrator' =>
  class BenSampo\Enum\Tests\Enums\UserType#102 (3) {
    public $key =>
    string(18) "SuperAdministrator"
    public $value =>
    int(3)
    public $description =>
    string(19) "Super administrator"
  }
}
```

`coerce(mixed $enumKeyOrValue): ?Enum`
指定されたキーまたは値を使用して、新しい列挙型のインスタンス化を試みます。列挙型をインスタンス化できない場合はnullを返します。

``` php
UserType::coerce(0);
// UserType::Administratorに設定されたUserTypeのインスタンスを返す
UserType::coerce('Administrator');
// UserType::Administratorに設定されたUserTypeのインスタンスを返す
UserType::coerce(99);
// nullを返す(not a valid enum value)
```
なかなか便利ですね〜
でも他にも便利な使い方があったんです！
※ 記事作成のために調べていて初めて知ったものが多いのは秘密

`is`と`isNot`
任意の値と等しいかを確認できる
※ isNotもあるけど極力使わない実装を心がけたい（願望）

``` php
$admin = UserType::fromValue(UserType::Administrator);

$admin->is(UserType::Administrator);   // true
$admin->is($admin);                    // true
$admin->is(UserType::Administrator()); // true

$admin->is(UserType::Moderator);       // false
$admin->is(UserType::Moderator());     // false
$admin->is('random-value');            // false
```

`in`と`notIn`
引数の値に含まれているかを確認できる
地味に知らなかったので使いどころ見つけたら楽できそう

``` php
$admin = UserType::fromValue(UserType::Administrator);

$admin->in([UserType::Moderator, UserType::Administrator]);     // true
$admin->in([UserType::Moderator(), UserType::Administrator()]); // true

$admin->in([UserType::Moderator, UserType::Subscriber]);        // false
$admin->in(['random-value']);                                   // false

$admin->notIn([UserType::Moderator, UserType::Administrator]);     // false
$admin->notIn([UserType::Moderator(), UserType::Administrator()]); // false

$admin->notIn([UserType::Moderator, UserType::Subscriber]);        // true
$admin->notIn(['random-value']);                                   // true
```

## 最後に
今回の記事のために改めて調べてみたのですが
まだ他にも使い方がある、、。
この記事は自分の確認用としても適宜更新していきたいと思います。

参考
https://github.com/BenSampo/laravel-enum#instance-properties