1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

RelicAdvent Calendar 2022

Day 13

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

Last updated at Posted at 2022-12-12

PHP Enum(列挙型)基礎 対話編の続きです

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

後「"Laravel Enum Helper"でググったら、早速使えそうなのをみつけましたよ。Laravel Newsで」
先「どんなん?」

archtechx/enums: Helpers for making PHP enums more lovable.

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

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

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

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に変換できますよ」

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があります。」

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ってのもありますよ。」

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",...,]
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があるんですよ。」

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しかプロパティw持てない、ってのもあったよね」
後「一応、プロパティ的なものを簡単に増やす機能も...ありますよ...」

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ってのを使ってるらしいです」
先「プロパティではなく、あくまで関数の追加なんやね。]
先「なんか黒魔術感があるなあ。おれ、Javaのアノテーションとかも苦手やったから..」

そして

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

おしまい。

1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?