PHP and Enumerations

后端 未结 30 1394
有刺的猬
有刺的猬 2020-11-22 13:39

I know that PHP doesn\'t have native Enumerations. But I have become accustomed to them from the Java world. I would love to use enums as a way to give predefined values whi

相关标签:
30条回答
  • 2020-11-22 14:17

    My attempt to create an enum with PHP...it's extremely limited since it doesn't support objects as the enum values but still somewhat useful...

    class ProtocolsEnum {
    
        const HTTP = '1';
        const HTTPS = '2';
        const FTP = '3';
    
        /**
         * Retrieve an enum value
         * @param string $name
         * @return string
         */
        public static function getValueByName($name) {
            return constant('self::'. $name);
        } 
    
        /**
         * Retrieve an enum key name
         * @param string $code
         * @return string
         */
        public static function getNameByValue($code) {
            foreach(get_class_constants() as $key => $val) {
                if($val == $code) {
                    return $key;
                }
            }
        }
    
        /**
         * Retrieve associate array of all constants (used for creating droplist options)
         * @return multitype:
         */
        public static function toArray() {      
            return array_flip(self::get_class_constants());
        }
    
        private static function get_class_constants()
        {
            $reflect = new ReflectionClass(__CLASS__);
            return $reflect->getConstants();
        }
    }
    
    0 讨论(0)
  • 2020-11-22 14:19

    I use interface instead of class:

    interface DaysOfWeek
    {
        const Sunday = 0;
        const Monday = 1;
        // etc.
    }
    
    var $today = DaysOfWeek::Sunday;
    
    0 讨论(0)
  • 2020-11-22 14:19

    Now you can use The SplEnum class to build it natively. As per the official documentation.

    SplEnum gives the ability to emulate and create enumeration objects natively in PHP.

    <?php
    class Month extends SplEnum {
        const __default = self::January;
    
        const January = 1;
        const February = 2;
        const March = 3;
        const April = 4;
        const May = 5;
        const June = 6;
        const July = 7;
        const August = 8;
        const September = 9;
        const October = 10;
        const November = 11;
        const December = 12;
    }
    
    echo new Month(Month::June) . PHP_EOL;
    
    try {
        new Month(13);
    } catch (UnexpectedValueException $uve) {
        echo $uve->getMessage() . PHP_EOL;
    }
    ?>
    

    Please note, it's an extension which has to be installed, but not available by default. Which comes under Special Types described in the php website itself. The above example is taken from the PHP site.

    0 讨论(0)
  • 2020-11-22 14:21

    There is a native extension, too. The SplEnum

    SplEnum gives the ability to emulate and create enumeration objects natively in PHP.

    http://www.php.net/manual/en/class.splenum.php

    Attention:

    https://www.php.net/manual/en/spl-types.installation.php

    The PECL extension is not bundled with PHP.

    A DLL for this PECL extension is currently unavailable.

    0 讨论(0)
  • 2020-11-22 14:22

    The most common solution that I have seen to enum's in PHP has been to create a generic enum class and then extend it. You might take a look at this.

    UPDATE: Alternatively, I found this from phpclasses.org.

    0 讨论(0)
  • 2020-11-22 14:22

    Pointed out solution works well. Clean and smooth.

    However, if you want strongly typed enumerations, you can use this:

    class TestEnum extends Enum
    {
        public static $TEST1;
        public static $TEST2;
    }
    TestEnum::init(); // Automatically initializes enum values
    

    With an Enum class looking like:

    class Enum
    {
        public static function parse($enum)
        {
            $class = get_called_class();
            $vars = get_class_vars($class);
            if (array_key_exists($enum, $vars)) {
                return $vars[$enum];
            }
            return null;
        }
    
        public static function init()
        {
            $className = get_called_class();
            $consts = get_class_vars($className);
            foreach ($consts as $constant => $value) {
                if (is_null($className::$$constant)) {
                    $constantValue = $constant;
                    $constantValueName = $className . '::' . $constant . '_VALUE';
                    if (defined($constantValueName)) {
                        $constantValue = constant($constantValueName);
                    }
                    $className::$$constant = new $className($constantValue);
                }
            }
        }
    
        public function __construct($value)
        {
            $this->value = $value;
        }
    }
    

    This way, enum values are strongly typed and

    TestEnum::$TEST1 === TestEnum::parse('TEST1') // true statement

    0 讨论(0)
提交回复
热议问题