Management and design of PHP enumeration types

藏色散人
Release: 2023-04-08 12:36:02
forward
3446 people have browsed it

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 = '否';
Copy after login

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

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

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

BoolEnum::YES(); // 是
BoolEnum::NO(); // 否
Copy after login

We can also obtain enumeration types in batches

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

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 = '否';
}
Copy after login

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];
    }
}
Copy after login

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

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

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);
    }
}
Copy after login

This can avoid users from using illegal enumerations Type value

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

or as parameter type qualification

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

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!

Related labels:
php
source:learnku.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!