Home >Backend Development >PHP Tutorial >Management and design of PHP enumeration types

Management and design of PHP enumeration types

藏色散人
藏色散人forward
2020-02-13 13:42:543544browse

The implementation of this article is mainly based on the myclabs/php-enum extension package.

Today I will share how to manage PHP enumeration types.

A common way is to use constants to represent enumeration types

const YES = '是';
const NO = '否';

You can go further on this basis and encapsulate them into classes for easier management

class BoolEnum {
    const YES = '是';
    const NO = '否';
}

Now, we hope to dynamically call the corresponding enumeration type through methods

BoolEnum::YES(); // 是
BoolEnum::NO(); // 否

We can also obtain enumeration types in batches

BoolEnum::toArray(); // ['Yes' => '是', 'No' => '否']

to implement the functions listed above.

Define the basic enumeration base class so that all enumeration classes inherit this abstract base class.

abstract class Enum
{   
    // 获取所有枚举类型
    public static function toArray(){
        // 通过反射获取常量
        $reflection = new \ReflectionClass(static::class);
        $contants = $reflection->getConstants();
        // 返回对应的常量
        return $contants;
    }
    //  动态调用属性
    public static function __callStatic($name, $arguments)
    {
        $arr = static::toArray();
        if(isset($arr[$name])){
            return $arr[$name];
        }
        throw new \BadMethodCallException("找不到对应的枚举值 {$name}");
    }
}
class BoolEnum extends Enum
{
    const YES = '是';
    const NO = '否';
}

Using reflection, all enumeration types can be obtained. At the same time, the magic method can be used to dynamically call attributes. It should be noted here that reflection consumes more resources. Therefore, the toArray method is reconstructed and a cache variable is added to cache the obtained enumeration type to avoid repeated use of reflection.

abstract class Enum
{   
    protected static $cache = [];
    public static function toArray(){
        $class = static::class;
        // 第一次获取,就通过反射来获取
        if(! isset(static::$cache[$class])){
            $reflection = new \ReflectionClass(static::class);
            static::$cache[$class] = $reflection->getConstants();
        }
        return static::$cache[$class];
    }
}

Now consider more usage scenarios, such as using instances to represent specific enumeration types

$yes = new BoolEnum("是");
echo $yes; // "是"

The implementation is as follows

abstract Enum 
{
    protected $value;
    public function __construct($value)
    {   
        if ($value instanceof static) {
            $value = $value->getValue();
        }
        if(! $this->isValid($value)){
            throw new \UnexpectedValueException("$value 不属于该枚举值" . static::class);
        }
        $this->value = $value;
    }
    // 获取实例对应的键
    public function getKey(){
        return array_search($this->value, static::toArray(), true);
    }
    // 获取实例对应的值
    public function getValue()
    {
        return $this->value;
    }
    // 允许字符串形式输出
    public function __toString()
    {
        return $this->value;
    }
    // 验证值是否合法
    public function isValid($value)
    {
      $arr = static::toArray();
      return in_array($value, $arr, true);
    }
    // 验证键是否合法
    public function isValidKey($key)
    {
      $arr = static::toArray();
      return array_key_exists($key, $arr);
    }
}

This can avoid users from using illegal enumerations Type value

$user->banned = '非法值';  // 可能不会报错
$yes = new BoolEnum("非法值"); // 将会抛出异常
$user->banned = $yes;

or as parameter type qualification

function setUserStatus(BoolEnum $boolEnum){
    $user->banned = $boolEnum;
}

PHP is a weakly typed language, insufficient parameter qualification will lead to many unexpected errors. By using enumeration classes, we The function of parameter limitation is further strengthened, and at the same time, the management of enumeration types is more convenient and unified.

The above is the detailed content of Management and design of PHP enumeration types. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:learnku.com. If there is any infringement, please contact admin@php.cn delete