LoginSignup
1
0

More than 3 years have passed since last update.

PHPの列挙型(enum)を実装

Last updated at Posted at 2019-09-06

参考元:
http://stackoverflow.com/a/2324746/1003020
http://stackoverflow.com/a/254543/1003020

Javaの経験がある方ならEnumが欲しいと思ったことあると思います。実装じに定数の記入ミス等に便利です。DBの値として利用することもおすすめします。

Abstractクラス

Enum.php
<?php
/**
 * Implements the abstract base for all constant types
 **/
namespace App\Enums;

/**
 * Class Enum
 * @package App\Enums
 */
abstract class Enum
{
    /**
     * キャッシュ用の変数
     *
     * @var null
     */
    private static $constCacheArray = NULL;

    /**
     * Enum constructor.
     *
     * make sure there are never any instances created
     */
    final private function __construct()
    {
        throw new Exception( 'Enum and Subclasses cannot be instantiated.' );
    }

    /**
     * Enum名の存在チェック
     *
     * @param $name
     * @param bool $strict
     * @return bool
     * @throws \ReflectionException
     */
    public static function isValidName($name, $strict = false)
    {
        $constants = self::getConstants();

        if ($strict) {
            return array_key_exists($name, $constants);
        }

        $keys = array_map('strtolower', array_keys($constants));
        return in_array(strtolower($name), $keys);
    }

    /**
     * Enumの値を存在チェック
     *
     * @param $value
     * @param bool $strict
     * @return bool
     * @throws \ReflectionException
     */
    public static function isValidValue($value, $strict = true)
    {
        $values = array_values(self::getConstants());
        return in_array($value, $values, $strict);
    }

    /**
     * Enum名でEnumを取得
     * @param $name
     * @return bool
     * @throws \ReflectionException
     */
    public static function fromString($name)
    {
        if (self::isValidName($name, $strict = true)) {
            $constants = self::getConstants();
            return $constants[$name];
        }

        return false;
    }

    /**
     * EnumからEnum名を取得
     *
     * @param $value
     * @return bool|false|int|string
     * @throws \ReflectionException
     */
    public static function toString($value)
    {
        if (self::isValidValue($value, $strict = true)) {
            return array_search($value, self::getConstants());
        }

        return false;
    }

    /**
     * Enumの値を取得
     *
     * @return array
     * @throws \ReflectionException
     */
    public static function getValues() {
        return array_values(self::getConstants());
    }

    /**
     * Enumを取得
     *
     * @return mixed
     * @throws \ReflectionException
     */
    private static function getConstants()
    {
        if (self::$constCacheArray == NULL) {
            self::$constCacheArray = [];
        }
        $calledClass = get_called_class();
        if (!array_key_exists($calledClass, self::$constCacheArray)) {
            $reflect = new \ReflectionClass($calledClass);
            self::$constCacheArray[$calledClass] = $reflect->getConstants();
        }
        return self::$constCacheArray[$calledClass];
    }
}

使い方

ColorEnum.php

/**
 * Class php:ColorEnum
 * @package App\Enums
 */
class php:ColorEnum extends Enum
{
    /**
     * 赤
     */
    const Red = 'FF0000';
    /**
     * 緑
     */
    const GREEN = '00FF00';
    /**
     * 青
     */
    const BLUE = '00000ff';
}

使い方を纏めました。

$mainColor = ColorEnum::Red                      // (string) 'FF0000'
DayOfWeek::isValidName('Red')                    // (bool) true
DayOfWeek::isValidName('red', $strict = true)    // (bool) false
DayOfWeek::isValidValue('FF0000')                // (bool) true
DayOfWeek::fromString('Red')                     // (string) 'FF0000'
DayOfWeek::toString(ColorEnum::Red)              // (string) "Red"
DayOfWeek::toString('FF0000')                    // (string) "Red"
DayOfWeek::getValues()                           // (array) ['FF0000', '00FF00', '0000FF']
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0