dnl-blkv/simple-php-enum

一个类似C/C++的简单枚举库。

0.6.2 2017-04-14 07:38 UTC

This package is not auto-updated.

Last update: 2024-09-29 02:39:16 UTC


README

描述

一个简单的PHP枚举库,类似于C/C++。

统计数据和健康状态

Travis CI codecov Latest Stable Version License

PHP版本支持

该包是新的,因此只支持PHP >=7.0

基本用法

安装

  1. 安装composer
  2. 在终端打开您的项目文件夹
  3. 输入 composer require dnl-blkv/simple-php-enum
  4. 等待composer完成工作
  5. 现在,您可以按照以下说明开始使用Simple PHP Enums!

定义枚举

使用该包定义基本枚举非常简单

use dnl_blkv\enum\AbstractEnum;

/**
 * @method static static CAT()
 * @method static static DOG()
 * @method static static BIRD()
 * @method static static FISH()
 */
class AnimalEnum extends AbstractEnum
{
    const CAT = null;
    const DOG = null;
    const BIRD = null;
    const FISH = null;
}

在这里,null表示自动确定的序数值,或自动序数值。默认的自动序数值为0。后续的自动序数值按{上一个序数} + 1确定。

枚举常量名称必须符合PSR-1规范,并且必须以大写字母开头。如果常量名称不符合规则,则忽略该常量。

创建

一旦定义了类,就可以按以下方式获取枚举

$animal = AnimalEnum::CAT();

或者

$animal = AnimalEnum::getByName('CAT');

或者

$animal = AnimalEnum::getByOrdinal(0);

在上面的示例中,如果未定义名称或序数,将抛出异常(分别对应于UndefinedEnumNameExceptionUndefinedEnumOrdinalException)。

访问

您可以访问枚举的名称(字符串表示)和序数(数字表示)

echo $animal->getName() . ' ' . $animal->getOrdinal(); // Outputs "CAT 0"

比较

相等性

枚举可以这样检查相等性

$cat = AnimalEnum::CAT();
$otherCat = AnimalEnum::CAT();
$dog = AnimalEnum::DOG();
var_dump($cat->isEqual($otherCat)) // Outputs "bool(true)"
var_dump($cat->isEqual($dog)) // Outputs "bool(false)"

直观上,不同类型的两个枚举永远不会相等。如果我们有一个类型为SomeOtherEnum的枚举,其中const VALUE = 0;,则以下成立

var_dump(SomeOtherEnum::VALUE()->isEqual(AnimalEnum::CAT())) // Outputs "bool(false)"

按序数比较

还可以通过序数值比较Simple PHP Enums。为此定义了四个方法,如下所示

/**
 * @method static static READ()
 * @method static static WRITE()
 * @method static static ADMIN()
 */
class AccessLevelEnum extends Enum
{
    const READ = null;
    const WRITE = null;
    const ADMIN = null;
}

var_dump(AccessLevelEnum::READ()->isLess(AccessLevelEnum::WRITE())) . PHP_EOL // -> "bool(true)"
var_dump(AccessLevelEnum::READ()->isGreater(AccessLevelEnum::WRITE())) . PHP_EOL // -> "bool(false)"
var_dump(AccessLevelEnum::READ()->isGreaterOrEqual(AccessLevelEnum::READ())) . PHP_EOL // -> "bool(true)"
var_dump(AccessLevelEnum::READ()->isLessOrEqual(AccessLevelEnum::ADMIN())) . PHP_EOL // -> "bool(true)"

如果比较不同类型的两个枚举,则抛出InvalidArgumentException

高级用法

使用自定义序数定义枚举

除了让库自动分配序数之外,您还可以手动将自定义整数值分配给序数

use dnl_blkv\enum\AbstractEnum;

/**
 * @method static static PIZZA()
 * @method static static SUSHI()
 * @method static static KEBAB()
 * @method static static SALAD()
 */
class FoodEnum extends AbstractEnum
{
    const PIZZA = 5;
    const SUSHI = null;
    const KEBAB = 8;
    const SALAD = 10;
}

在这种情况下,枚举将被定义为以下内容

echo FoodEnum::PIZZA()->getOrdinal() . PHP_EOL; // Outputs "5"
echo FoodEnum::SUSHI()->getOrdinal() . PHP_EOL; // Outputs "6"
echo FoodEnum::KEBAB()->getOrdinal() . PHP_EOL; // Outputs "8"
echo FoodEnum::SALAD()->getOrdinal() . PHP_EOL; // Outputs "10"

重复序数

类似于纯C/C++枚举,这个Simple PHP Enums允许重复序数。这可以用于处理默认值等类似情况

use dnl_blkv\enum\AbstractEnum;

/**
 * @method static static LAGER()
 * @method static static IPA()
 * @method static static PORTER()
 * @method static static STOUT()
 * @method static static DEFAULT()
 * @method static static AFTER_DEFAULT()
 */
class BeerEnum extends AbstractEnum
{
    const LAGER = 0;
    const IPA = null;
    const PORTER = null;
    const STOUT = null;
    const DEFAULT = 0;
    const AFTER_DEFAULT = null;
}

对于上面定义的枚举,以下将成立

echo BeerEnum::DEFAULT()->getOrdinal() . PHP_EOL; // Outputs "0"
echo BeerEnum::AFTER_DEFAULT()->getOrdinal() . PHP_EOL; // Outputs "1"

如果您通过魔术方法或名称获取具有重复序数的枚举,它将按常规工作。

echo BeerEnum::DEFAULT()->getName() . PHP_EOL; // Outputs "DEFAULT"
echo BeerEnum::getByName('DEFAULT')->getName() . PHP_EOL; // Outputs "DEFAULT"

然而,如果您通过序数获取它,行为略有不同,您有两种选择,如下所示

echo BeerEnum::getFirstByOrdinal(0)->getName() . PHP_EOL; // Outputs "LAGER"
$allEnumWithOrdinalZero = BeerEnum::getAllByOrdinal(0);
echo $allEnumWithOrdinalZero[0]->getName() . PHP_EOL; // Outputs "LAGER"
echo $allEnumWithOrdinalZero[1]->getName() . PHP_EOL; // Outputs "DEFAULT"

更多相等性

Simple PHP Enum库只创建每个枚举对象一次,然后重用它。因此,枚举可以通过===或其别名isSame进行比较。这种比较比isEqual更严格。而isEqual只考虑枚举类型和序数,isSame还考虑name

var_dump(BeerEnum::LAGER()->isEqual(BeerEnum::LAGER())); // Outputs "bool(true)"
var_dump(BeerEnum::LAGER()->isEqual(BeerEnum::DEFAULT())); // Outputs "bool(true)"
var_dump(BeerEnum::LAGER() === BeerEnum::LAGER()); // Outputs "bool(true)"
var_dump(BeerEnum::LAGER() === BeerEnum::DEFAULT()); // Outputs "bool(false)"
var_dump(BeerEnum::LAGER()->isSame(BeerEnum::LAGER())); // Outputs "bool(true)"
var_dump(BeerEnum::LAGER()->isSame(BeerEnum::DEFAULT())); // Outputs "bool(false)"

检查名称和序数是否存在

如果您想检查某个枚举类型是否具有给定的名称或序数,有方法可以轻松完成此操作

var_dump(BeerEnum::isNameDefined('STOUT')) // Outputs "bool(true)";
var_dump(BeerEnum::isNameDefined('VODKA')) // Outputs "bool(false)";
var_dump(BeerEnum::isOrdinalDefined(3)) // Outputs "bool(true)";
var_dump(BeerEnum::isOrdinalDefined(420)) // Outputs "bool(false)";

转换为字符串

枚举具有内嵌的魔法机制进行序列化

echo BeerEnum::IPA() . PHP_EOL;

/* 
 * Outputs:
 * {
 *     "\your\name\space\BeerEnum": {
 *         "name": "IPA",
 *         "ordinal": 1
 *      }
 * }
 */

注意

扩展

AbstractEnum 类的所有内部成员都是 publicprotected 的。因此,它完全开放以供扩展,允许你在此基础上构建更复杂的结构。

与数据库一起使用

如果你选择将枚举与数据库一起使用并存储序号,我建议确保没有存储的枚举具有重复的序号。否则,可能会出现存储 DEFAULT = 0,但在重新创建时接收到 IPA = 0 的情况。