はじめまして、ぎゅうです。
皆さん、Enumは利用されていますか?
「いや、まだ使ったことないですね」という方も多いはずです。
PHP8.1から実装されたEnum。
他の言語では馴染み深いEnumですが、実はPHPではこれまでありませんでした。
私はLaravel8を利用した開発にあたって、このEnumをガッツリ使うことになりました。
今回は実際にenumを利用してみて、「基本的にこう使えばいい」とわかったので、紹介していきます。
もし、超使いこなしていますという方がいれば、次の記事を読み進めてみてくださいね
便利メソッドの紹介の前に簡単にEnumについて紹介をしていきます
Enumを定義しよう
まずEnumはclassではありません。
そのため、
enum ExampleEnum: int
{
//
}
のように記述していきます。
: intで型定義をしています。
Enumで定数を利用する
続いて, roleなどの定数を定義していきます
enum ExampleEnum: int
{
case status1 = 1;
case status2 = 2;
case status3 = 3;
case status4 = 4;
}
Enumではcaseを書いて、定数を宣言していきます。
ここはclassとは違いますよね
オブジェクトとの違いも公式ドキュメントで解説されています。
valueでcaseの値を取得しよう
ここまで読み進めると、こんな疑問が浮かぶはずです。
caseを定義したのはいいけど、どうやって値を取得するの?
実はcaseで定義した値を取得したい場合は、value
を利用します。
ExampleEnum::status1->value;
// 1
valueを利用することで値を取得できるので、実にシンプルですよね。
Enumで用意されているメソッド3選
定数を定義したところで、Enumで元から用意されているメソッドについて理解していきましょう。
cases()メソッド
cases()メソッドを利用すると、Enumで定義したcaseの一覧をarrayで取得できます。
ExampleEnum::cases();
// [ ExampleEnum::status1, ExampleEnum::status2, ExampleEnum::status3, ExampleEnum::status4]
これで一覧を取得できるため、繰り返し処理などに利用します。
しかし、これ単体では利用頻度は低めです。
なぜなら、
- Laravelのvalidationでは有効なenumの値が含まれているか判定する、Enumルールが用意されている
- データ整形してからデータを渡したいため、データ整形するためのメソッド内でcases()を利用する。
上記2点のことから、あまりない気がします。
Laravelのvalidationに関しては下記のようにnew Enum()
のRuleを利用すれば、一覧を必要としません。
use App\Enums\ExampleEnum;
use Illuminate\Validation\Rules\Enum;
$request->validate([
'status' => [new Enum(ExampleEnum::class)],
]);
この例では、ExampleEnumで定義された定数の値でないとエラーになります。
先ほど1~4の定数を定義しているので、投稿された値が1~4でなければvalidationで弾くことになります。
enum ExampleEnum: int
{
case status1 = 1;
case status2 = 2;
case status3 = 3;
case status4 = 4;
}
これがあるので、cases()を使う機会もグッと減ったわけです。
先ほどの例をみると、
「enumはclassではないのに、どうして::classを使っているの???」
と疑問が生まれるかもしれません。
::class()は名前空間(namespace)を取得するメソッドです。これにより
ExampleEnum::class
// App\Enums\ExampleEnumを出力
を取得され、無事にExampleEnumを読み込まれるわけです。
::classをなんとなく利用されていた方は、公式ドキュメントを読んでみもいいかもしれません。
ということで、enumのcases()に関しては便利ではあるが、利用頻度は少ない印象でした。
とはいえ、元から用意されているのはありがたいですよね。
from()メソッド
ここまで読まれた方は、こんな疑問があったはずです。
Enumで定義した定数は、どうやって使うの?
この疑問を解消するのが、from()メソッドです。
ExampleEnum::from(1)
// ExampleEnum::status1を取得
fromメソッドを利用することで、Enumで定義した定数とmatchするとその定数を取得します。
fromで定数をmatchするとpublic function やprivate function などのstaticではない関数を利用することができます
enum ExampleEnum: int
{
case status1 = 1;
case status2 = 2;
case status3 = 3;
case status4 = 4;
/**
* hogeを取得
* @return string
*/
public function hoge(): string
{
return 'hoge';
}
}
ExampleEnum::from(1)->hoge(); // staticでないメソッドが利用可能
classのインスタンスのように利用できます。
enumで定義したメソッドを利用するには、form()かとtryFrom()をまず利用していきましょう。
tryFrom()メソッド
fromメソッドとほぼ同じです。
ExampleEnum::tryFrom(5);
// null
nullを返してくれるので、不要なエラーを出したくない場合に非常に便利です。
tryFromで取得をして、メソッドを利用したい場合は、null安全オペレータを利用していきましょう。
ExampleEnum::tryFrom(5)->hoge(); // nullなので、hoge()メソッドでエラーが出力
ExampleEnum::tryFrom(5)?->hoge(); // nullの場合,hoge()を実行しない
tryFrom()とnull安全オペレータの組み合わせで、エラーなくアプリを動作できるわけです。
何か確実に出力させたい場合は、??
を組み合わせるとよいでしょう。
ExampleEnum::tryFrom(5)?->hoge() ?? '該当する値はありません';
まとめ
それではまとめていきましょう
- enumのcaseの値は
value
で取得 - 基本的に
tryFrom()
でcaseを取得するのが無難。エラーを出したいケースはfrom()
を利用する。 tryFrom()
を利用した場合、null安全オペレータ
を利用してエラーを避けよう。
ということでした。
Enumで定義しておくと便利なメソッドは下記の記事で紹介しているので、ぜひ一読してみてくださいね。
コメント