ynkt/enum-like

此包已被弃用且不再维护。未建议替代包。

类似 Enum 的 PHP 实现

v1.1.0 2020-10-22 19:33 UTC

This package is auto-updated.

Last update: 2022-09-22 23:57:00 UTC


README

目录

为什么

我创建这个库是为了让 Enum 能够在许多情况下使用。

这个库有以下优点

  • 每个枚举可以声明多个值
  • 您可以从各种数据源声明 Enum,例如类常量、数据库或配置文件

要求

  • PHP ^7.4

安装

composer require ynkt/enum

使用方法

Enum 是一个抽象类,需要扩展才能使用。

基本声明

以下代码使用类常量来声明 Enum。

注意

- 在编写 __constructor() 时使用受保护的可见性

- 不要声明与枚举名称相同的命名方法

use Ynkt\Enum\Enum;

/**
 * Class Status
 */
class Status extends Enum
{
    private const READY = 'Ready';
    private const IN_PROGRESS = 'In Progress';
    private const DONE = 'Done';

    private string $text;

    // The argument of __constructor() is automatically assigned to the value of the enumerator
    protected function __construct(string $text) { $this->text = $text; }

    public function text(): string { return $this->text; }
}

静态方法

// Provided by this library
Status::values(); // Returns instances of the Enum class of all Enumerators
Status::first(); // Returns the first instance
Status::first(callable $closure); // Returns the first instance that passes a given truth
Status::has(callable $closure); // Tests an instance exists that passes a given truth

// Provided by the user declaration
// This library automatically provide the static method whose name is same of the enumerators name.
// The following methods return an Enum instance.
Status::READY();
Status::IN_PROGRESS();
Status::DONE();

具有与枚举名称相同的名称的静态方法由 __callStatic() 实现。

因此,如果您关心 IDE 自动完成,我建议您使用如下 phpdoc

/**
 * Class Status
 * 
 * @method static self READY()
 * @method static self IN_PROGRESS()
 * @method static self DONE()
 */
class Status extends Enum
{
    private const READY = 'Ready';
    private const IN_PROGRESS = 'In Progress';
    private const DONE = 'Done';

    // ...
}

实例方法

$status = Status::READY();

// Provided by this library
$status->name(); // Returns the name of the current enumerator (e.g.:'READY')
$status->ordinal(); // Returns the ordinal of the current enumerator (e.g.:0)
$status->declaringClass(); // Returns the declaring class of the current enumerator (e.g.:'Status')
$status->equals(Status::Ready()); // Tests enum instances are equal (e.g.:true)

// Provided by the user declaration
$status->text(); // Returns 'Ready'

类型提示

您可以使用继承自 Enum 的类进行类型提示。

function updateStatus(Status $status){
  // ...
}

updateStatus(Status::READY());

如何为每个枚举声明多个值

如果您想为每个枚举声明多个值,您可以分配一个数组。

class Color extends Enum
{
    private const RED = ['#FF0000', [255, 0, 0]];
    private const BLUE = ['#0000FF', [0, 0, 255]];
    private const BLACK = ['#000000', [0, 0, 0]];

    // The argument of __constructor() is automatically assigned to the value of the enumerator
    protected function __construct(string $code, array $rgb) {}

    // ...
}

如何从各种数据源声明 Enum

如果您想根据不是类常量的数据声明 Enum,您可以覆盖 getConstants()

以下两种声明方式是等价的。

class ColorFromDataSource extends Enum
{
    /**
     * @overwrite
     */
    protected static function getConstants(string $class): array
    {
        return [
            'RED'   => ['#FF0000', [255, 0, 0]],
            'BLUE'  => ['#0000FF', [0, 0, 255]],
            'BLACK' => ['#000000', [0, 0, 0]],
        ];
    }

    // ...
}
class Color extends Enum
{
    private const RED = ['#FF0000', [255, 0, 0]];
    private const BLUE = ['#0000FF', [0, 0, 255]];
    private const BLACK = ['#000000', [0, 0, 0]];

    // ...
}

提示

如果您想通过标识符或其他方式获取实例

使用标识符作为获取实例的方式是一种常见模式。因此,为了实现这一点,我已准备了 ByIdTrait 以根据 ID 获取实例。

class DayOfWeek extends Enum
{
    use ByIdTrait;

    private const MONDAY = 1;
    private const TUESDAY = 2;

    private int $id;   

    public function id(): int { return $this->id; }

    // ...
}

// You can use byId() to get the Enum instance.
$dayOfWeek = DayOfWeek::byId(1);
$dayOfWeek->equals(DayOfWeek::MONDAY()); // Returns true

我认为 ByIdTrait 的实现将在您根据一些标识符获取实例时非常有帮助。

示例

https://github.com/ynkt/enum/tree/master/tests/示例