PHP
laravel
laravel5

Laravel-enumの使い方

はじめに

RailsでEnumを使っての開発に慣れてしまっていて、Laravelでも使いたかったので調べてみた。

環境

  • PHP7.1
  • Laravel5.6

1. enumとは

Wikipediaから以下抜粋

列挙型(れっきょがた、enumerated type)とは、コンピュータプログラミングにおいて、プログラマが選んだ各々の識別子をそのまま有限集合として持つ抽象データ型である。列挙型は一般に、カードのスートのように番号順を持たないカテゴリ変数として使われるが、実際のコンパイル時あるいは実行時には、列挙型は整数で実装されることが多い。各々の識別子は通例異なる整数値を持つが、複数の識別子に対して意図的に同じ整数値を割り当てる(つまり別名を定義する)ことも可能である。

また列挙型は、整数を使用する場合と比較して、明示的にマジックナンバーを使用するよりもプログラムソースの可読性を改善するのに役立つ。言語によっては、列挙型の整数表現はプログラマに見えないようになっていることもあり、これによりプログラマが列挙値に対して算術演算を行うような乱用を防いでいる。

言語によっては、真偽値の論理型は、あらかじめ宣言された二値の列挙型とされている。

例えば、公開非公開みたいなフラグをboolean型で定義したとします。
実際にDBに格納される値は01だったときに、文字列としては、公開非公開を扱いたい場合などにenumはとても便利です。

2. パッケージ

Laravelにはenumを扱えるパッケージが二つありました。

パッケージ githubスター数 情報量
laravel-enum 71 そんなにない
laravel-enums 24 そんなにない

上記を見る限り大差はないように見受けられました。

ドキュメントを見た感じ、前者のlaravel-enumの方がわかりやすかったので、そちらを採用しました。

3. 導入

$ composer require bensampo/laravel-enum

composerでインストールしたら、php artisan make:enumコマンドが使えるようになります。

4. 使ってみる

上の例でもあげたように公開非公開用のenumを作成していこうと思います。

$ php artisan make:enum PublishStateType

以上を実行するとappディレクトリ配下にEnumsディレクトリが作成され、その中にPublishStateType.phpが生成されます。

PublishStateType.phpを見てみると以下のようになっている

<?php

namespace App\Enums;

use BenSampo\Enum\Enum;

final class PublishStateType extends Enum
{
    const OptionOne = 0;
    const OptionTwo = 1;
    const OptionThree = 2;

    /**
     * Get the description for an enum value
     *
     * @param $value
     * @return string
     */
    public static function getDescription($value): string
    {
        if ($value === self::OptionOne) {
            return 'Option one';
        }

        return parent::getDescription($value);
    }
}

を以下のようにします。

<?php

namespace App\Enums;

use BenSampo\Enum\Enum;

final class PublishStateType extends Enum
{
    const Private = 0;
    const Public = 1;

    /**
     * Get the description for an enum value
     *
     * @param $value
     * @return string
     */
    public static function getDescription($value): string
    {
        switch ($value){
            case self::Private:
                return '非公開';
                brake;
            case self::Public:
                return '公開';
                brake;
            default:
                return self::getKey($value);
        }
    }
}

以上でPublishStateTypeの設定は一旦OKです。

5. コントローラーで使う

use App\Enums\PublishStateType;

をコントローラーの上部へ記述し、

PublishStateType::getDescription('0'); // 非公開
PublishStateType::getDescription('1'); // 公開

のように扱えます。

6. ビューで使う

ビューで使う場合は、フルパスで記述をして使います。

<p>{{\App\Enums\PublishStateType::getDescription('0')}}</p> // 非公開
<p>{{\App\Enums\PublishStateType::getDescription('1')}}</p> // 公開

となります。

7. getValueをカスタマイズする

getValueという定義されたメソッドを使えば、定数で定義したキーを引数に入れることで定数の値を取得することが出来る。

<p>{{\App\Enums\PublishStateType::getValue('Private')}}</p> // 0
<p>{{\App\Enums\PublishStateType::getValue('Public')}}</p> // 1

しかし、やりたかったことは、
PrivatePublicではなく、公開非公開という文字列から定数の値を取得したかった

そこでgetValueメソッドをカスタマイズする。
PublishStateType.phpを開き以下のようにする

<?php

namespace App\Enums;

use BenSampo\Enum\Enum;

final class PublishStateType extends Enum
{
    const Private = 0;
    const Public = 1;

    /**
     * Get the description for an enum value
     *
     * @param $value
     * @return string
     */
    public static function getDescription($value): string
    {
        switch ($value){
            case self::Private:
                return '非公開';
                brake;
            case self::Public:
                return '公開';
                brake;
            default:
                return self::getKey($value);
        }
    }

    public static function getValue(string $key)
    {
        switch ($key){
            case '非公開':
                return 0;
            case '公開':
                return 1;
            default:
                return self::getValue($key);
        }
    }
}
<p>{{\App\Enums\PublishStateType::getValue('非公開')}}</p> // 0
<p>{{\App\Enums\PublishStateType::getValue('公開')}}</p> // 1

public static function getvalueでオーバーライドして、非公開という文字列ならば0を返し、公開なら1を返すということを実現出来る。