此包已被废弃,不再维护。未建议替代包。

一个轻量级的库,用于在PHP中创建枚举,不使用SPLEnum,允许严格比较

1.0.0 2020-12-05 10:17 UTC

README

Mutation testing badge Type Coverage Latest Stable Version License

枚举

一个轻量级的库,用于在PHP中创建枚举,不使用SPLEnum,允许严格比较。

免责声明

对于基于PHP >=8.1的项目,请使用此rfc中描述的内置枚举语言:https://wiki.php.net/rfc/enumerations 此库将不再需要,并且不会支持PHP >=8.1。

安装

composer require patchlevel/enum

声明

首先,您必须定义您的枚举。为此,您需要从《Enum》类继承,创建一些常量(值必须是唯一的字符串)并定义返回枚举表示的方法。以下是一个示例

<?php

declare(strict_types=1);

namespace Patchlevel\Enum\Example;

use Patchlevel\Enum\Enum;

/**
 * @psalm-immutable
 */
final class Status extends Enum
{
    private const CREATED = 'created';
    private const PENDING = 'pending';
    private const RUNNING = 'running';
    private const COMPLETED = 'completed';

    public static function created(): self
    {
        return self::get(self::CREATED);
    }

    public static function pending(): self
    {
        return self::get(self::PENDING);
    }

    public static function running(): self
    {
        return self::get(self::RUNNING);
    }

    public static function completed(): self
    {
        return self::get(self::COMPLETED);
    }
}

self::get()确保确实存在一个表示实例,以便可以无问题地使用严格比较。

或者,您可以继承ExtendedEnum,它提供了一些便利,更多关于这一点在ExtendedEnum下讨论。

API

使用枚举

<?php 

declare(strict_types=1);

namespace Patchlevel\Enum\Example;

$status = Status::completed();

if ($status === Status::completed()) {
    echo "That's working";
}

// or use as typehint

function isFinished(Status $status): bool {
    return $status === Status::completed();
}

echo isFinished($status) ? 'yes' : 'no'; 

// or with the new php8.0 match feature:

$message = match ($status) {
    Status::created() => 'Process created',
    Status::pending() => 'Process pending',
    Status::running() => 'Process running',
    Status::completed() => 'Process completed',
    default => 'unknown status',
};

echo $message; // Process completed

由于它确保只有一个特定值的实例,因此严格比较不会成为问题。

fromString

您可以从字符串创建一个枚举。内部会检查值是否有效,否则会抛出InvalidValue异常。

$status = Status::fromString('pending');

if ($status === Status::pending()) {
    echo 'it works';
}

toString

相反,枚举也可以转换回字符串。

$status::completed();
echo $status->toString(); // completed

equals

Equals方法只是$a === $b的包装。

$status = Status::completed();
$status->equals(Status::pending()); // false

isValid

isValid可以用来检查传递的值是否有效。返回值是一个布尔值。

Status::isValid('foo'); // false
Status::isValid('completed'); // true

values

您还可以获取所有Enum实例。

$instances = Status::values();

foreach ($instances as $instance) {
    echo $instance->toString(); // completed, pending, ...
}

keys

或所有键。

$keys = Status::keys();

foreach ($keys as $key) {
    echo $key; // completed, pending, ...
}

扩展枚举

或者,它也可以扩展自ExtendedEnum。此实现还提供了其他功能,主要是魔法方法:__toString__callStatic和实现\JsonSerializable

<?php

declare(strict_types=1);

namespace Patchlevel\Enum\Example;

use Patchlevel\Enum\ExtendedEnum;

/**
 * @psalm-immutable
 * @method static self CREATED()
 * @method static self PENDING()
 * @method static self RUNNING()
 * @method static self COMPLETED()
 */
final class Status extends ExtendedEnum
{
    private const CREATED = 'created';
    private const PENDING = 'pending';
    private const RUNNING = 'running';
    private const COMPLETED = 'completed';
}

__callStatic

通过魔法方法__callStatic,您可以根据常量名称创建枚举实例。因此不需要定义额外的函数。如果枚举中不存在该常量名称,将抛出BadMethodCall异常。

$status = Status::CREATED();

__toString

只是toString的魔法方法实现。

$status = Status::CREATED();
echo (string)$status; // created

JsonSerializable

ExtendedEnum已经实现了接口\JsonSerializablejsonSerialize方法。这意味着\json_encode将自动以正确的方式序列化值。请注意,\json_decode不会自动将其解码回枚举。这项工作必须手动完成。请参阅此示例

$status = Status::CREATED();
echo json_encode($status, JSON_THROW_ON_ERROR); // "created"