承接 nelexa/enum 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

nelexa/enum

Composer 安装命令:

composer require nelexa/enum

包简介

PHP Enum implementation

README 文档

README

Packagist Version Packagist Build Status Scrutinizer Code Quality Code Coverage Build Status License

Table of Contents

Installation

composer require nelexa/enum

Enum declaration

<?php

use Nelexa\Enum;

/**
 * @method static self PENDING()
 * @method static self ACTIVE()
 * @method static self INACTIVE()
 * @method static self DELETED()
 */
class UserStatus extends Enum
{
    public const
        PENDING = 1,
        ACTIVE = 1 << 1,
        INACTIVE = 1 << 2,
        DELETED = 1 << 3;
}

Usage

$enum = UserStatus::ACTIVE();

assert($enum instanceof UserStatus);
assert($enum->name() === 'ACTIVE');
assert($enum->value() === 1 << 1);
assert($enum->ordinal() === 1);

To loop a enum object

foreach (UserStatus::values() as $userStatus) {
    printf('User status: %s, status id: %d, ordinal: %d' . PHP_EOL,
        $userStatus->name(),
        $userStatus->value(),
        $userStatus->ordinal()
    );
}

Output:

User status: PENDING, status id: 1, ordinal: 0
User status: ACTIVE, status id: 2, ordinal: 1
User status: INACTIVE, status id: 4, ordinal: 2
User status: DELETED, status id: 8, ordinal: 3

To compare the enum values, use === operator

$userStatus = UserStatus::DELETED();
if ($userStatus === UserStatus::DELETED()) {
    echo 'User status: ' . $userStatus->name() . PHP_EOL;
}

Convert a string to enum object

$enum = UserStatus::valueOf('ACTIVE');

assert(UserStatus::ACTIVE() === UserStatus::valueOf('ACTIVE'));

Convert a value to enum object

$enum = UserStatus::valueOf('ACTIVE');
$value = $enum->value();

assert(UserStatus::fromValue($value) === $enum);
assert(UserStatus::fromValue($value) === UserStatus::valueOf('ACTIVE'));

Switch case

$enum = UserStatus::PENDING();
switch ($enum) {
    case UserStatus::ACTIVE():
        echo 'Active status';
        break;
    case UserStatus::PENDING():
        echo 'Pending status';
        break;
    case UserStatus::DELETED():
        echo 'Delete status';
        break;
    case UserStatus::INACTIVE():
        echo 'Inactive status';
        break;
    default:
        throw new \RuntimeException('Invalid value');
}

Output:

Pending status

Use enum in the type hint

/**
 * @var UserStatus
 */
private $status;

public function setStatus(UserStatus $status): void
{
    $this->status = $status;
}

public function getStatus(): UserStatus
{
    return $this->status;
}

public function isActive(): bool
{
    return $this->status === UserStatus::ACTIVE();
}

Example

$user->setStatus(UserStatus::INACTIVE());
echo sprintf('User status is %s.' . PHP_EOL, $user->getStatus()->name());

Output:

User status is INACTIVE

Add some logic to enum

<?php

/**
 * @method static self PLUS()
 * @method static self MINUS()
 * @method static self TIMES()
 * @method static self DIVIDE()
 */
class Operation extends \Nelexa\Enum
{
    private const
        PLUS = null,
        MINUS = null,
        TIMES = null,
        DIVIDE = null;

    /**
     * Do arithmetic op represented by this constant
     *
     * @param float $x
     * @param float $y
     * @return float
     */
    public function calculate(float $x, float $y): float
    {
        switch ($this) {
            case self::PLUS():
                return $x + $y;
            case self::MINUS():
                return $x - $y;
            case self::TIMES():
                return $x * $y;
            case self::DIVIDE():
                return $x / $y;
        }
        throw new \AssertionError('Unknown op: ' . $this->name());
    }
}

Example

echo Operation::PLUS()->calculate(4, 2);   // 6
echo Operation::TIMES()->calculate(4, 2);  // 8
echo Operation::MINUS()->calculate(4, 2);  // 2
echo Operation::DIVIDE()->calculate(4, 2); // 2

Initialization of values ​​without constructor

For example consider the planets of the solar system. Each planet knows its mass and radius, and can calculate its surface gravity and the weight of an object on the planet.

Here is how it looks:

<?php
declare(strict_types=1);

use Nelexa\Enum;

/**
 * Class Planet
 *
 * @method static self MERCURY()
 * @method static self VENUS()
 * @method static self EARTH()
 * @method static self MARS()
 * @method static self JUPITER()
 * @method static self SATURN()
 * @method static self URANUS()
 * @method static self NEPTUNE()
 * @method static self PLUTO()
 *
 * @see https://docs.oracle.com/javase/8/docs/technotes/guides/language/enums.html
 */
class Planet extends Enum
{
    private const
        MERCURY = [3.303e+23, 2.4397e6],
        VENUS = [4.869e+24, 6.0518e6],
        EARTH = [5.976e+24, 6.37814e6],
        MARS = [6.421e+23, 3.3972e6],
        JUPITER = [1.9e+27, 7.1492e7],
        SATURN = [5.688e+26, 6.0268e7],
        URANUS = [8.686e+25, 2.5559e7],
        NEPTUNE = [1.024e+26, 2.4746e7],
        PLUTO = [1.27e+22, 1.137e6];

    /**
     * @var double universal gravitational constant (m3 kg-1 s-2)
     */
    private static $G = 6.67300E-11;

    /**
     * @var double in kilograms
     */
    private $mass;
    /**
     * @var double in meters
     */
    private $radius;

    /**
     * In this method, you can initialize additional variables based on the
     * value of the constant. The method is called after the constructor.
     *
     * @param string|int|float|bool|array|null $value the enum scalar value of the constant
     */
    protected function initValue($value): void
    {
        [$this->mass, $this->radius] = $value;
    }

    public function mass(): float
    {
        return $this->mass;
    }

    public function radius(): float
    {
        return $this->radius;
    }

    public function surfaceGravity(): float
    {
        return self::$G * $this->mass / ($this->radius * $this->radius);
    }

    public function surfaceWeight(float $otherMass): float
    {
        return round($otherMass * $this->surfaceGravity(), 6);
    }
}

The enum Planet class contains the initValue($value) method, and each enum constant is declared with a value that to be passed to this method when it is created.

Here is a sample program that takes your weight on earth (in any unit) and calculates and prints your weight on all of the planets (in the same unit):

$earthWeight = 175;
$mass = $earthWeight / Planet::EARTH()->surfaceGravity();
foreach (Planet::values() as $p) {
    printf("Your weight on %s is %f\n", $p->name(), $p->surfaceWeight($mass));
}

Output:

Your weight on MERCURY is 66.107583
Your weight on VENUS is 158.374842
Your weight on EARTH is 175.000000
Your weight on MARS is 66.279007
Your weight on JUPITER is 442.847567
Your weight on SATURN is 186.552719
Your weight on URANUS is 158.397260
Your weight on NEPTUNE is 199.207413
Your weight on PLUTO is 11.703031

Class Synopsis

abstract class Nelexa\Enum {

    /* Methods */
    final public static valueOf ( string $name ) : static
    final public name ( void ) : string
    final public value ( void ) : string | int | float | bool | array | null
    final public static values ( void ) : static[]
    final public static containsKey ( string $name ) : bool
    final public static containsValue ( mixed $value [, bool $strict = true ] ) : bool
    final public static function fromValue( mixed $value ): static
    final public ordinal ( void ) : int
    public __toString ( void ) : string
    protected static function getEnumConstants(): array
}

Usage tips

  • Even though it is not mandatory to declare enum constants with UPPERCASE letters, it is in the best practice to do so.
  • Enum classes can have fields and methods along with enum constants.
  • Enum constructors are private. Only private constructors are allowed in enum classes. That’s why you can’t instantiate enum types using a new operator.
  • Enum constants are created only once for the whole execution. All enum constants are created when you initially refer any enum constant in your code.
  • Enum types can implement any number of interfaces.
  • We can compare the enum constants using the === operator.
  • You can retrieve the enum constants of any enum type using the values() static method. The values() static method returns an array of enum constants.
  • The ordinal() static method is used to get the order of an enum constant in an enum type.
  • Enums are mostly used when you want to allow a limited set of options that remain constant for the whole execution and you know all possible options. For example, this could be choices on a menu or options of a combobox.
  • Use private constants to exclude prompts from your IDE.
  • Use PHPDoc to describe static enum initialization methods.

Generate PHPDoc for enum class

To use hints in the IDE, you need to declare special comments on the class with a list of static methods.

The \Nelexa\enum_docblock($enumOrEnumClass) function should help with this.

echo \Nelexa\enum_docblock(Planet::class);
// or
echo \Nelexa\enum_docblock(Planet::MERCURY());

Output:

/**
 * @method static self MERCURY()
 * @method static self VENUS()
 * @method static self EARTH()
 * @method static self MARS()
 * @method static self JUPITER()
 * @method static self SATURN()
 * @method static self URANUS()
 * @method static self NEPTUNE()
 * @method static self PLUTO()
 */

Changelog

Changes are documented in the releases page.

License

The files in this archive are released under the MIT License.

You can find a copy of this license in LICENSE file.

nelexa/enum 适用场景与选型建议

nelexa/enum 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 524.56k 次下载、GitHub Stars 达 1, 最近一次更新时间为 2019 年 05 月 14 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「enum」 「enumeration」 「enumerator」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 nelexa/enum 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 nelexa/enum 我们能提供哪些服务?
定制开发 / 二次开发

基于 nelexa/enum 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 524.56k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 19
  • 依赖项目数: 5
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2019-05-14