Help us understand the problem. What is going on with this article?

PHPで列挙型(enum)を作る

More than 1 year has passed since last update.

列挙型 - Wikipedia

まず列挙型の定義は〜となるんだけど、ここでは「あらかじめ定義した値のいずれかしか取らない特殊な型」という感じを想定してます。
要はSplEnumみたいなのですが、拡張モジュールの力を借りなくても、PHPだけで作れます。リフレクションを使うだけ。

<?php
abstract class Enum
{
    private $scalar;

    public function __construct($value)
    {
        $ref = new ReflectionObject($this);
        $consts = $ref->getConstants();
        if (! in_array($value, $consts, true)) {
            throw new InvalidArgumentException;
        }

        $this->scalar = $value;
    }

    final public static function __callStatic($label, $args)
    {
        $class = get_called_class();
        $const = constant("$class::$label");
        return new $class($const);
    }

    //元の値を取り出すメソッド。
    //メソッド名は好みのものに変更どうぞ
    final public function valueOf()
    {
        return $this->scalar;
    }

    final public function __toString()
    {
        return (string)$this->scalar;
    }
}
使い方
<?php
// トランプのスート型を定義する。4種類しか値を取らない。
// Enumをextendして、定数をセット
final class Suit extends Enum
{
    const SPADE = 'spade';
    const HEART = 'heart';
    const CLUB = 'club';
    const DIAMOND = 'diamond';
}

//インスタンス化
$suit = new Suit(Suit::SPADE);
echo $suit; //toString実装済みなので文字列キャスト可能

echo $suit->valueOf(); //生の値を取り出す。intやfloat等の場合に。

// 適当な値を突っ込もうとすると、InvalidArgumentExceptionが発生して停止
//$suit = new Suit('uso800');



//__callStaticを定義してあるのでnewを使わずこんな感じでも書ける(PHP5.3以降)
$suit = Suit::SPADE();

PHPには組み込みのEnum型はないので、無理にEnumを作った所で速度的な旨味はありません。ただ、型チェックだけで「この定義済みの値のいずれかである」ことが保証できます。

ユーザーの入力なんかを予め検証して、適当な型にキャストしておけば、以降は型チェックだけで安心してデータを扱えるようになります。べんり。

<?php

function doSomething(Suit $suit) {
    //Suitというタイプヒントによって、
    //$suitは必ず4種類のうちのどれかだと保証されている

}

元の値を取り出すメソッド名に困ったので、JavaScript風にvalueOf()にしてますが、まあ別に何でもOKです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした