Closed11

php-enumのメモ

なおなお

定義
wikipediaの列挙型の例を使った
https://ja.wikipedia.org/wiki/列挙型#C言語

use MyCLabs\Enum\Enum;

class Cardsuit extends Enum
{
    public const CLUBS = 1;
    public const DIAMONDS = 2;
    public const HEARTS = 3;
    public const SPADES = 4;
}

なおなお

クラスなのでこういう書き方もできる

use MyCLabs\Enum\Enum;

class Cardsuit extends Enum
{
    public const CLUBS = 'C';
    public const DIAMONDS = 'D';
    public const HEARTS = 'H';
    public const SPADES = 'S';
}

なおなお

使ってみる

// 定数
echo Cardsuit::CLUBS;
>>> 1

// メソッド
// 内部で__callStatic()が呼び出されて、インスタンスが返ってくる
$cardsuit =  Cardsuit::DIAMONDS();
var_dump($cardsuit);
>>> object(Cardsuit)#3 (2) {
  ["value":protected]=>
  int(2)
  ["key":"MyCLabs\Enum\Enum":private]=>
  string(8) "DIAMONDS"
}

なおなお

こういう使い方もできる

$key = 'HEARTS';
$cardsuit =  Cardsuit::$key();
var_dump($cardsuit);
>>> object(Cardsuit)#2 (2) {
  ["value":protected]=>
  int(3)
  ["key":"MyCLabs\Enum\Enum":private]=>
  string(6) "HEARTS"
}

// 値からインスタンス生成が可能
// fromメソッドがいきなり登場
$cardsuit =  Cardsuit::from(3);
var_dump($cardsuit);
>>> object(Cardsuit)#4 (2) {
  ["value":protected]=>
  int(3)
  ["key":"MyCLabs\Enum\Enum":private]=>
  string(6) "HEARTS"
}

// もちろんclassなので、これもできる
// __constructの引数は値を指定することでインスタンス生成が可能
$cardsuit =  new Cardsuit(4);
var_dump($cardsuit);
>>> object(Cardsuit)#5 (2) {
  ["value":protected]=>
  int(4)
  ["key":"MyCLabs\Enum\Enum":private]=>
  string(6) "SPADES"
}

なおなお

staticメソッド

メソッド 用途てきな 使い方てきな
from 指定した定数値のインスタンスを生成
存在しない時は例外発生
$cardsuit = Cardsuit::from(3);
$cardsuit = Cardsuit::from(9999); -> 例外
keys 定数名の一覧を取得 $keys = Cardsuit::keys();
values キーが定数名、値がインスタンスの配列を取得 $values = Cardsuit::values();
toArray キーが定数名、値が定数値の配列を取得 $array = Cardsuit::toArray();
isValid 指定した定数値が存在しているか Cardsuit::isValid(1); -> true
Cardsuit::isValid(99); -> false
isValidKey 指定した定数名が存在しているか Cardsuit::isValidKey('CLUBS'); -> true
Cardsuit::isValidKey('AAAA'); -> false
assertValidValue 指定した定数値が存在しているか
存在しない時は例外発生
Cardsuit::assertValidValue(1); -> null
Cardsuit::assertValidValue(99); -> 例外(UnexpectedValueException)
search 指定した定数値の定数名を取得 Cardsuit::search(1); -> CLUBS
Cardsuit::search(99); -> false
__callStatic 定数をメソッドとして呼び出す
内部的にはnew クラス名がうごく
Cardsuit::CLUBS();
なおなお

メソッド

メソッド 用途てきな 使い方てきな
__construct 指定した定数値のインスタンスを生成
定数値が存在しないときは例外がおきる
new Cardsuit(1);
__wakeup unserializeを実行した時にうごく
__toString 定数値を表示 $cardsuit = Cardsuit::DIAMONDS();
echo $cardsuit; -> 2
getValue インスタンスの定数値を取得 $cardsuit = Cardsuit::HEARTS();
$cardsuit->getValue(); -> 3
getKey インスタンスの定数名を取得 $cardsuit = Cardsuit::from(3);
$cardsuit->getKey(); -> HEARTS
equals 同じ定数であるか検証 $cardsuit = Cardsuit::SPADES();
$cardsuit->equals(Cardsuit::SPADES()); -> true
$cardsuit->equals(Cardsuit::DIAMONDS()); -> false
jsonSerialize json_encodeでシリアライズするデータを返す
https://www.php.net/manual/ja/jsonserializable.jsonserialize.php
なおなお

もちろんクラスなのでメソッドを定義することもできる
動かしていた環境がphp7.4だったのでmatch式は使えなかった

use MyCLabs\Enum\Enum;

class Cardsuit extends Enum
{
    public const CLUBS = 1;
    public const DIAMONDS = 2;
    public const HEARTS = 3;
    public const SPADES = 4;

    /**
     * 日本語を返す
     */
    public function label(): string
    {
        switch ($this->value) {
            case self::CLUBS:
                $label = 'クラブ';
                break;
            case self::DIAMONDS:
                $label = 'ダイヤモンド';
                break;
            case self::HEARTS:
                $label = 'ハート';
                break;
            case self::SPADES:
                $label = 'スペード';
                break;
        }
        return $label;
    }
}

foreach (Cardsuit::values() as $value) {
    var_dump($value->label());
}
>>> string(9) "クラブ"
string(18) "ダイヤモンド"
string(9) "ハート"
string(12) "スペード"
なおなお

php8の環境を用意した

    public function label(): string
    {
        return match($this->value) {
            self::CLUBS => 'クラブ',
            self::DIAMONDS => 'ダイヤモンド',
            self::HEARTS => 'ハート',
            self::SPADES => 'スペード',
        };
    }

foreach (Cardsuit::values() as $value) {
    var_dump($value->label());
}
>>> string(9) "クラブ"
string(18) "ダイヤモンド"
string(9) "ハート"
string(12) "スペード"
このスクラップは2022/05/30にクローズされました