列挙型はクラスに似ていますし、 クラスやインターフェイス、トレイトと名前空間を共有します。 列挙型はオートローディングも可能です。 列挙型は新しい型を定義しますが、 固定の、限られた数の有効な値を持ちます。
<?php
enum Suit
{
case Hearts;
case Diamonds;
case Clubs;
case Spades;
}
?>
上記の宣言によって、新しい列挙型
Suit
が作られますが、
これが持つ有効な値は4つだけです。
Suit::Hearts
、Suit::Diamonds
、Suit::Clubs
、そして Suit::Spades
です。
これらの有効な値のうち、ひとつだけを変数に代入できます。
関数は列挙型に対する型チェックを行えますし、
その場合は列挙型の値だけが渡せます。
<?php
function pick_a_card(Suit $suit)
{
/* ... */
}
$val = Suit::Diamonds;
// OK
pick_a_card($val);
// OK
pick_a_card(Suit::Clubs);
// TypeError: pick_a_card(): Argument #1 ($suit) must be of type Suit, string given
pick_a_card('Spades');
?>
列挙型は、0個以上の
case
を定義できます。
case
を定義する数に上限はありません。
case が0個の列挙型も文法的には有効ですが、役に立ちません。
列挙型の case は、PHP のラベルと同じ規則に従います。 定数 のページを参照ください。
デフォルトでは、case は本質的にスカラーの値に依存していません。
つまり、Suit::Hearts
は "0"
に等しくないということです。
むしろ、それぞれの case はその名前が付いたシングルトンオブジェクトです。
以下のコードがそれを示しています:
<?php
$a = Suit::Spades;
$b = Suit::Spades;
$a === $b; // true
$a instanceof Suit; // true
?>
このことは、列挙型の値は決して
<
や >
で比較できないことも意味しています。
なぜなら、それらの比較をオブジェクトで行っても無意味だからです。
列挙型の値を使ってこれらの比較を行っても、常に false
を返します。
関連するデータのない、こうしたタイプの case を、 "Pure Case" と呼びます。 Pure Case のみを含む列挙型を、"Pure Enum" と呼びます。
全ての Pure Case は、その列挙型のインスタンスとして実装されています。 列挙型は内部的にクラスとして表現されます。
全ての case は読み取り専用のプロパティ
name
を持ちます。
これは大文字小文字が区別される、case そのものの名前です。
<?php
print Suit::Spades->name;
// "Spades" と表示
?>
列挙型の名前を動的に取得している場合、 case の存在を確認したり、読み取る用途として defined() や constant() 関数が使えます。 しかしながら、これらの関数の利用はおすすめできません。 なぜなら、 Backed Enum で大半の用途を満たせるはずだからです。