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を導入してみることになりましたとさ。
おしまい。