对于PHP中enum的好奇

简介: PHP中没有struct、enum这些东西,虽然万能的array用起来很爽,但写出来的代码typo问题很多、可维护性也差,需要更多的测试来辅助,而一旦加上测试的工作量是否还谈得上『爽』就是个问号了。看了一篇研究Java enum机制的文章,文章里提到java的具体的enum其实就是一个类,重点是它的每一个枚举值也是一个enum对象。

PHP中没有struct、enum这些东西,虽然万能的array用起来很爽,但写出来的代码typo问题很多、可维护性也差,需要更多的测试来辅助,而一旦加上测试的工作量是否还谈得上『爽』就是个问号了。

看了一篇研究Java enum机制的文章,文章里提到java的具体的enum其实就是一个类,重点是它的每一个枚举值也是一个enum对象。

对照着用PHP初步实现了一下。PHP的__callStatic 不支持静态属性访问,所以暂时用静态方法的形式访问枚举值 (string) Color::RED()。

<?php

interface enum
{
    
}

/**
 * @method enum RED() Description
 */
final class Color implements enum
{    
    private static $enums = 
        [
            'RED' => [255, 0, 0],
            'BLUE' => [0, 0, 255],
            'BLACK' => [0, 0, 0],
            'YELLOW' => [255, 255, 0],
            'GREEN' => [0, 255, 0]
        ];
    private static $objs = [];
    
    private $name;
    
    public static function __callStatic($name, $arguments)
    {
        if (!array_key_exists($name, static::$enums)) {
            throw new Exception('enum not existed', -1);
        }
        
        return static::valueOf($name);
    }
    
    private function setName($val): void
    {
        $this->name = $val;
    }
    
    private static function initEnum(string $name): bool
    {
        if (isset(static::$objs[$name])) {
            return true;
        }
        
        if (!array_key_exists($name, static::$enums)) {
            throw new Exception('enum not existed', -1);
        }
        
        $obj = new Color();
        $obj->setName($name);
        
        static::$objs[$name] = $obj;
        
        return true;
    }
    
    public static function values(): array
    {
        if (empty(static::$objs)) {
            foreach (array_keys(static::$enums) as $name) {
                static::initEnum($name);
            }
        }
        
        return static::$objs;
    }
    
    public static function valueOf(string $name): enum
    {
        if (!array_key_exists($name, static::$enums)) {
            throw new Exception('enum not existed', -1);
        }
        
        static::initEnum($name);
        
        return static::$objs[$name];
    }
    
    public function ordinal(): int
    {
        //TODO
        return 0;
    }
    
    /**
     * @throws ClassCastException
     */
    public function compareTo(enum $other): int
    {
        //TODO
        return -1;
    }
    
    public function equals(enum $other): bool
    {
        //TODO
        return true;
    }
    
    public function __toString()
    {
        if (!$this->name) {
            return '';
        }
        
        return '(' . implode(',', static::$enums[$this->name]) . ')';
    }
}  


echo (string) Color::RED();
echo (string) Color::valueOf('BLACK');

代码并没有做细致的抽象,如果要进一步抽象的话,可以试试定义一个EnumTraits来包含那些公共方法。

会不会有人问,既然你这么喜欢Java的enum,为什么不直接用Java得了。

目录
相关文章
|
7月前
|
关系型数据库 MySQL PHP
PHP 原生操作 Mysql
PHP 原生操作 Mysql
81 0
|
7月前
|
关系型数据库 MySQL 数据库连接
PHP 原生连接 Mysql
PHP 原生连接 Mysql
107 0
|
7月前
|
关系型数据库 MySQL Unix
PHP MySql 安装与连接
PHP MySql 安装与连接
130 0
|
3月前
|
关系型数据库 MySQL PHP
|
11天前
|
PHP
web简易开发——通过php与HTML+css+mysql实现用户的登录,注册
web简易开发——通过php与HTML+css+mysql实现用户的登录,注册
|
7月前
|
关系型数据库 MySQL 数据库连接
PHP 原生操作 Mysql 增删改查案例
PHP 原生操作 Mysql 增删改查案例
87 0
|
2月前
|
监控 关系型数据库 MySQL
PHP与MySQL的结合:实现局域网上网行为监控软件的数据库管理
在当今信息化时代,网络安全日益成为重要的话题。为了有效监控和管理局域网上网行为,开发一个基于PHP和MySQL的数据库管理系统是一个理想的选择。本文将介绍如何结合PHP和MySQL,开发一款简单而高效的局域网上网行为监控软件,并重点关注数据库管理方面的实现。
198 0
|
8月前
|
运维 关系型数据库 MySQL
【运维知识进阶篇】集群架构-Nginx实现基础web架构(Linux+Nginx+PHP+Mysql)(二)
【运维知识进阶篇】集群架构-Nginx实现基础web架构(Linux+Nginx+PHP+Mysql)(二)
203 0
|
8月前
|
消息中间件 NoSQL 关系型数据库
Linux安装 OpenResty、Nginx、PHP、Mysql、Redis、Lua、Node、Golang、MongoDB、Kafka等
Linux安装 OpenResty、Nginx、PHP、Mysql、Redis、Lua、Node、Golang、MongoDB、Kafka等
106 0
|
4月前
|
NoSQL 关系型数据库 应用服务中间件
Linux安装 OpenResty、Nginx、PHP、Mysql、Redis、Lua、Node、Golang、MongoDB、Kafka等
Linux安装 OpenResty、Nginx、PHP、Mysql、Redis、Lua、Node、Golang、MongoDB、Kafka等
89 0