列挙型(Enum)にはメソッドやインターフェイスが追加できるように、定数も追加できます。
最初は『これいるんだろうか? Enumって定数の集まりだよね?』と思いましたが、よくよく考えてみると使いみちはあった。
case とconst はともに定数で参照する側からは同じなんですが、性格がちがいます。
意外と使えるかも。
冒頭でも言いましたが、最初に定数が追加できると聞いたとき、『それ、いる?』と思いました。
enumの定数
<?php
enum Car: int
{
case MATUDA = 1;
case HONDA = 2;
case TOYOTA = 3;
case SUZUKI = 4;
const AREA = [
'Africa',
'America',
'Asia',
'Euro',
];
}
enumもクラスの一種なので、constが定義できます。Backed Enum なので caseの値はintで制限されますが、定数の型はそれにしばられません。
enumのネストはできない
なんで定数はいらないと思ったかというと、こうすればいいじゃんって思ったから。
<?php
enum Area
{
case Africa;
case America;
case Asia;
case Euro;
}
enum Car: int
{
case MATUDA = 1;
case HONDA = 2;
case TOYOTA = 3;
case SUZUKI = 4;
const AREA = Area;
}
var_dump(Car::AREA);
var_dump(Car::MATUDA::AREA);
これ、できそうなんですけどエラーになります。
実行結果
PHP Fatal error: Uncaught Error: Undefined constant "Area" in /home/vagrant/php8-test.php:21
Stack trace:
#0 {main}
thrown in /home/vagrant/php8-test.php on line 21
考えてみたら納得できます。通常のクラスでも、クラスの型そのものを変数に代入することはできません。
<?php
class Area
{
const Africa = '1';
const America = '2';
const Asia = '3';
const Euro = '4';
}
$test1 = new Area();
$test2 = Area::Africa;
$test3 = Area;
実行結果
PHP Fatal error: Uncaught Error: Undefined constant "Area" in /home/vagrant/php8-test.php:13
Stack trace:
#0 {main}
thrown in /home/vagrant/php8-test.php on line 13
それと同じです。ただし、クラス Area内の定数が参照できるように、enum内のcaseを参照することはできます。
<?php
enum Area
{
case Africa;
case America;
case Asia;
case Euro;
}
enum Car: int
{
case MATUDA = 1;
case HONDA = 2;
case TOYOTA = 3;
case SUZUKI = 4;
const AREA = Area::Africa; // <-- ここ
}
var_dump(Car::AREA);
var_dump(Car::MATUDA::AREA);
実行結果
enum(Area::Africa)
enum(Area::Africa)
こうなるなら、定数は意外と便利です。使いみちはあります。
Enumクラスはシングルトンでインスタンスは作成しないので、変数に代入できない。
Enum内のcaseクラスはインスタンスなので変数に代入できる。
しかし、ここでは意味がない。
定数値に自身のcase値も使える。
さっきのサンプルは、よそのenumのcaseを定数に代入しましたが、自分自身のcase値も代入できます。
<?php
enum Car: int
{
case MATUDA = 1;
case HONDA = 2;
case TOYOTA = 3;
case SUZUKI = 4;
const TOP_MAKER = self::TOYOTA; // <-- ここ
}
var_dump(Car::TOP_MAKER);
var_dump(Car::MATUDA::TOP_MAKER);
実行結果
enum(Car::TOYOTA)
enum(Car::TOYOTA)
なんか使い道ありそうな意味の定数を用意してサンプルを作りましたが、これはそこまで使うことはなさそう。
PHP公式ドキュメント