列挙型の強化
PHP 8.2には、列挙型の利用における機能強化もあります。列挙型とはenum型とも呼ばれ、列挙子と呼ばれる特定の値のみを所持することのできる型です。このために、まずはPHP 8.1でサポートされた列挙型を紹介しておきます。
列挙型[PHP 8.1]
列挙型(Enumerations)は、PHP 8.1でサポートされました。列挙型のサポートされていないバージョンでは、定数を使って列挙子のようなものを定義するか、列挙型のようなクラスを作成していました。いずれも、以下のリストのように列挙子を個別に定義し、値を重複しないように割り振っていく必要があります。
// グローバルな定数を列挙子のように使う
const ANIMAL = 1;
const BIRD = 2;
const INSECT = 3;
printf("%d, %d, %d\n", ANIMAL, BIRD, INSECT); // 実行結果:1, 2, 3
// 列挙体のようなクラスを使う
class CreatureClass {
public const ANIMAL = 1;
public const BIRD = 2;
public const INSECT = 3;
}
printf("%d, %d, %d\n",
CreatureClass::ANIMAL, CreatureClass::BIRD, CreatureClass::INSECT);
// 実行結果:1, 2, 3
この方法には、それぞれ問題があります。グローバルな定数では、どの列挙子がどの列挙体(のようなもの)に属するのかということ、また割り振る値が重複しないようにすることは、プログラマが管理しなければなりません。クラスではスコープが利用できますが、やはり割り振る値は重複しないように、プログラマが管理しなければなりません。
列挙体では、上記のような定義は以下のリストのように置き換えることができます。
enum CREATURE (1)
{
case ANIMAL; (2)
case BIRD;
case INSECT;
public function text(): string (3)
{
return match($this) {
self::ANIMAL => '動物',
self::BIRD => '鳥類',
self::INSECT => '昆虫',
};
}
}
printf("%s は %s\n", CREATURE::ANIMAL->name, CREATURE::ANIMAL->text()); (4)
printf("%s は %s\n", CREATURE::BIRD->name, CREATURE::BIRD->text());
printf("%s は %s\n", CREATURE::INSECT->name, CREATURE::INSECT->text());
実行結果は、下記です。
ANIMAL は 動物 BIRD は 鳥類 INSECT は 昆虫
(1)のように、クラスの宣言と同様の構文で、enumキーワードによって列挙体を宣言できます。そして(2)以降で、caseキーワードで個々の列挙子を定義します。このとき、具体的な値は不要であることに注意してください。また(3)のように、列挙体ではクラスと同様にメソッドを定義できます。メソッド内部では、自分自身を表す$thisが使えるのもクラスと同じです。
(4)以降に、呼び出しのコードも示しています。定義したメソッドtextの呼び出しの他に、既定で使えるnameプロパティを参照して列挙子の名前を取得することも可能です。
値に依存した列挙型(Backed Enum)も使用できます。この場合は、列挙子の型と値を明示することになります。以下のリストでは、上記の列挙体CREATUREを値に依存した列挙型CREATURE_BACKEDとして定義し直しています。実行結果は、CREATUREの例と同じです。
enum CREATURE_BACKED: string (1)
{
case ANIMAL = '動物'; (2)
case BIRD = '鳥類';
case INSECT = '昆虫';
}
printf("%s は %s\n", CREATURE_BACKED::ANIMAL->name, CREATURE_BACKED::ANIMAL->value); (3)
printf("%s は %s\n", CREATURE_BACKED::BIRD->name, CREATURE_BACKED::BIRD->value);
printf("%s は %s\n", CREATURE_BACKED::INSECT->name, CREATURE_BACKED::INSECT->value);
(1)の列挙型CREATURE_BACKEDでは、型としてstringを指定しています。(2)のcaseキーワードで個々の列挙子を定義するのも同じですが、ここでは値を明示しています。(3)の呼び出しのコードでは、valueプロパティを参照して値を取得しています。このvalueプロパティも既定で使用できますが、値に依存した列挙型でのみ使用可能となっています。
定数式中のenumプロパティ[PHP 8.2]
PHP 8.2では、定数式の中で、列挙体のプロパティを使えるようになりました。例えば以下のリストのように定数の値を列挙子のプロパティで定義できます。
const ANIMAL_NAME = CREATURE::ANIMAL->name; const ANIMAL_VALUE = CREATURE_BACKED::ANIMAL->value; var_dump(ANIMAL_NAME); // 実行結果:string(6) "ANIMAL" var_dump(ANIMAL_VALUE); // 実行結果:string(6) "動物""
ここでは、nameプロパティとvalueプロパティをそれぞれ使用し、列挙子の名前と値を定数の値としています。同様に、列挙体に定義したメソッドの呼び出しも使うことができます。
