mindtwo/laravel-enum

此包已被弃用且不再维护。作者建议使用bensampo/laravel-enum 包。

为 Laravel 提供简单、可扩展且强大的枚举实现。

2.1.0 2020-03-23 14:16 UTC

README

Laravel Enum

Build Status Packagist Stable Version Packagist downloads MIT Software License

关于 Laravel Enum

为 Laravel 提供简单、可扩展且强大的枚举实现。

  • 枚举键值对作为类常量
  • 完整的函数集
  • 枚举实例化
  • 类型提示
  • 属性转换
  • 枚举 artisan 生成器
  • 验证规则,将枚举键或值作为输入参数
  • 本地化支持
  • 通过宏可扩展

Ben Sampson 创建

跳转到

指南

我写了一篇关于使用 laravel-enum 的博客文章:https://sampo.co.uk/blog/using-enums-in-laravel

要求

  • Laravel 5.4 或更高版本
  • PHP 7.1 或更高版本

安装

通过 Composer

composer require bensampo/laravel-enum

如果您使用的是 Laravel < 5.5,您需要将服务提供者添加到 config/app.php

'BenSampo\Enum\EnumServiceProvider'

枚举库

从常用、社区贡献的枚举列表中进行浏览和下载。

枚举库 →

基本用法

枚举定义

您可以使用以下 Artisan 命令生成一个新的枚举类

php artisan make:enum UserType

现在,您只需添加枚举可以有的可能值作为常量。

<?php

namespace App\Enums;

use BenSampo\Enum\Enum;

final class UserType extends Enum
{
    const Administrator = 0;
    const Moderator = 1;
    const Subscriber = 2;
    const SuperAdministrator = 3;
}

就这样!请注意,由于枚举值被定义为普通常量,因此您可以像访问任何其他类常量一样访问它们。

UserType::Administrator // Has a value of 0

实例化

实例化枚举以在函数之间传递是有用的,同时具有类型提示的优点。

此外,无法用无效值实例化枚举,因此您可以确信传递的值始终有效。

为了方便,枚举可以通过多种方式实例化

// Standard new PHP class, passing the desired enum value as a parameter
$enumInstance = new UserType(UserType::Administrator);

// Static getInstance method, again passing the desired enum value as a parameter
$enumInstance = UserType::getInstance(UserType::Administrator);

// Statically calling the key name as a method, utilizing __callStatic magic
$enumInstance = UserType::Administrator();

// Using the coerce static method to attempt to instantiate an Enum using the given value if it exists.
$enumInstance = UserType::coerce($someValue);

如果您希望您的 IDE 自动完成静态实例化辅助程序,您可以通过 artisan 命令生成 PHPDoc 注释。

默认情况下,所有位于 app/Enums 的 Enums 都会被注释(您可以通过传递路径到 --folder 来更改文件夹)

php artisan enum:annotate

您可以通过指定类名来注释单个类

php artisan enum:annotate "App\Enums\UserType"

实例属性

一旦你有了枚举实例,你可以将其keyvaluedescription作为属性访问。

$userType = UserType::getInstance(UserType::SuperAdministrator);

$userType->key; // SuperAdministrator
$userType->value; // 0
$userType->description; // Super Administrator

当你将枚举实例传递给blade视图时,这尤其有用。

实例转换

枚举实例可以转换为字符串,因为它们实现了__toString()魔法方法。
这也意味着它们可以在blade视图中输出,例如。

$userType = UserType::getInstance(UserType::SuperAdministrator);

(string) $userType // '0'

实例等价

你可以通过将其传递给is方法来检查实例与任何值的等价性。为了方便,还有一个isNot方法,它是is方法的相反操作。

$admin = UserType::getInstance(UserType::Administrator);

$admin->is(UserType::Administrator);   // true
$admin->is($admin);                    // true
$admin->is(UserType::Administrator()); // true

$admin->is(UserType::Moderator);       // false
$admin->is(UserType::Moderator());     // false
$admin->is('random-value');            // false

你也可以使用in方法检查实例的值是否与一组可能的值匹配。

$admin = UserType::getInstance(UserType::Administrator);

$admin->in([UserType::Moderator, UserType::Administrator]);     // true
$admin->in([UserType::Moderator(), UserType::Administrator()]); // true

$admin->in([UserType::Moderator, UserType::Subscriber]);        // false
$admin->in(['random-value']);                                   // false

类型提示

枚举实例的一个好处是它使你可以使用类型提示,如下所示。

function canPerformAction(UserType $userType)
{
    if ($userType->is(UserType::SuperAdministrator)) {
        return true;
    }

    return false;
}

$userType1 = UserType::getInstance(UserType::SuperAdministrator);
$userType2 = UserType::getInstance(UserType::Moderator);

canPerformAction($userType1); // Returns true
canPerformAction($userType2); // Returns false

属性转换

你可以使用CastsEnums特质将模型属性转换为枚举。这将使属性在获取时转换为枚举实例,在设置时转换回枚举值。

与标准属性转换类似,你只需在模型上定义一个数组,指定你想要转换到哪个枚举的属性。

use BenSampo\Enum\Traits\CastsEnums;
use BenSampo\Enum\Tests\Enums\UserType;
use Illuminate\Database\Eloquent\Model;

class Example extends Model
{
    use CastsEnums;

    protected $enumCasts = [
        // 'attribute_name' => Enum::class
        'user_type' => UserType::class,
    ];

    /**
     * Existing casts are processed before $enumCasts which can be useful if you're 
     * taking input from forms and your enum values are integers.
     */
    protected $casts = [
        'user_type' => 'int',
    ];
}

现在,当你访问你的Example模型的user_type属性时,将返回底层值,作为UserType枚举。

$example = Example::first();
$example->user_type // Instance of UserType

查看枚举实例上的方法和属性以充分利用属性转换。

你可以通过传递枚举值或另一个枚举实例来设置值。

$example = Example::first();

// Set using enum value
$example->user_type = UserType::Moderator;

// Set using enum instance
$example->user_type = UserType::Moderator();

模型注释

该包可以自动为你的Model类生成DocBlocks,以在你的IDE中提供类型提示和自动完成功能。

默认情况下,所有位于app根目录下的Model类都将被注释(你可以通过传递一个路径给--folder来更改文件夹)

php artisan enum:annotate-model

验证

数组验证

你可以使用EnumValue规则来验证传递给控制器的枚举值是否是给定枚举的有效值。

public function store(Request $request)
{
    $this->validate($request, [
        'user_type' => ['required', new EnumValue(UserType::class)],
    ]);
}

默认情况下,类型检查设置为严格,但你可以通过将false传递给EnumValue类的可选第二个参数来绕过此设置。

new EnumValue(UserType::class, false) // Turn off strict type checking.

你也可以使用EnumKey规则在键上执行验证。如果你将枚举键用作URL参数进行排序或过滤等,这很有用。

public function store(Request $request)
{
    $this->validate($request, [
        'user_type' => ['required', new EnumKey(UserType::class)],
    ]);
}

当然,这两者也可以在表单请求类上工作。

请确保在你的usings中包含BenSampo\Enum\Rules\EnumValue和/或BenSampo\Enum\Rules\EnumKey以及你的枚举类。

管道验证

你还可以使用'pipe'语法来使用EnumKey和EnumValue规则,分别使用enum_value和/或enum_key

enum_value:enum_class,[strict]
enum_key:enum_class

'user_type' => 'required|enum_value:' . UserType::class,
'user_type' => 'required|enum_key:' . UserType::class,

本地化

您可以使用 Laravel 内置的 本地化功能来翻译由 getDescription 方法返回的字符串。

为您的每种支持的语言添加一个新的 enums.php 键文件。在这个例子中,有一个英文和一个西班牙文。

// resources/lang/en/enums.php
<?php

use App\Enums\UserType;

return [

    UserType::class => [
        UserType::Administrator => 'Administrator',
        UserType::SuperAdministrator => 'Super administrator',
    ],

];
// resources/lang/es/enums.php
<?php

use App\Enums\UserType;

return [

    UserType::class => [
        UserType::Administrator => 'Administrador',
        UserType::SuperAdministrator => 'Súper administrador',
    ],

];

现在,您只需确保您的枚举实现如以下示例所示的 LocalizedEnum 接口。

use BenSampo\Enum\Enum;
use BenSampo\Enum\Contracts\LocalizedEnum;

final class UserType extends Enum implements LocalizedEnum
{
    // ...
}

getDescription 方法现在将查找本地化文件中的值。如果某个键不存在,将返回默认描述。

重写 getDescription 方法

如果您想在 getDescription 方法中返回自定义值,可以通过在枚举上重写该方法来实现。

public static function getDescription($value): string
{
    if ($value === self::SuperAdministrator) {
        return 'Super admin';
    }

    return parent::getDescription($value);
}

现在调用 UserType::getDescription(3); 返回 Super admin 而不是 Super administator

扩展 Enum 基类

Enum 基类实现了 Laravel 的 Macroable 特性,这意味着可以轻松地通过自己的函数来扩展它。如果您有一个经常添加到每个枚举中的函数,可以使用宏。

假设我们想要能够获取枚举 toArray 方法的反转版本,我们可以这样做:

Enum::macro('toFlippedArray', function() {
    return array_flip(self::toArray());
});

现在,我可以在每个枚举上使用它:UserType::toFlippedArray()

最好在服务提供者的 boot 方法中注册宏。

PHPStan 集成

如果您使用 PHPStan 进行静态分析,可以启用扩展以正确识别魔术实例化方法。

将以下内容添加到您的项目 phpstan.neon 包含中:

includes:
- vendor/bensampo/laravel-enum/extension.neon

Artisan 命令列表

php artisan make:enum

创建一个新的枚举类
了解更多信息

php artisan enum:annotate

为枚举类生成 DocBlock 注释
了解更多信息

php artisan enum:annotate-model

为具有枚举的模型生成 DocBlock 注释
了解更多信息

枚举类参考

static getKeys(): array

返回枚举的键数组。

UserType::getKeys(); // Returns ['Administrator', 'Moderator', 'Subscriber', 'SuperAdministrator']

static getValues(): array

返回枚举的值数组。

UserType::getValues(); // Returns [0, 1, 2, 3]

static getKey(mixed $value): string

返回给定枚举值的键。

UserType::getKey(1); // Returns 'Moderator'
UserType::getKey(UserType::Moderator); // Returns 'Moderator'

static getValue(string $key): mixed

返回给定枚举键的值。

UserType::getValue('Moderator'); // Returns 1

静态 hasKey(string $key): bool

检查枚举是否包含指定的键。

UserType::hasKey('Moderator'); // Returns 'True'

静态 hasValue(mixed $value, bool $strict = true): bool

检查枚举是否包含指定的值。

UserType::hasValue(1); // Returns 'True'

// It's possible to disable the strict type checking:
UserType::hasValue('1'); // Returns 'False'
UserType::hasValue('1', false); // Returns 'True'

静态 getDescription(mixed $value): string

返回枚举值的句型键。可以重写getDescription方法以返回自定义描述。

UserType::getDescription(3); // Returns 'Super administrator'
UserType::getDescription(UserType::SuperAdministrator); // Returns 'Super administrator'

静态 getRandomKey(): string

返回枚举中的一个随机键。对工厂类很有用。

UserType::getRandomKey(); // Returns 'Administrator', 'Moderator', 'Subscriber' or 'SuperAdministrator'

静态 getRandomValue(): mixed

返回枚举中的一个随机值。对工厂类很有用。

UserType::getRandomValue(); // Returns 0, 1, 2 or 3

静态 getRandomInstance(): mixed

返回枚举中的一个随机实例。对工厂类很有用。

UserType::getRandomInstance(); // Returns an instance of UserType with a random value

静态 toArray(): array

返回枚举键值对作为关联数组。

UserType::toArray(); // Returns ['Administrator' => 0, 'Moderator' => 1, 'Subscriber' => 2, 'SuperAdministrator' => 3]

静态 toSelectArray(): array

返回枚举以用于select中的value => description。

UserType::toSelectArray(); // Returns [0 => 'Administrator', 1 => 'Moderator', 2 => 'Subscriber', 3 => 'Super administrator']

静态 getInstance(mixed $enumValue): Enum

返回调用枚举的实例。更多关于枚举实例化的信息。

UserType::getInstance(UserType::Administrator); // Returns instance of Enum with the value set to UserType::Administrator

静态 getInstances(): array

返回所有可能的调用枚举实例的数组,按常量名称键控。

var_dump(UserType::getInstances());

array(4) {
  'Administrator' =>
  class BenSampo\Enum\Tests\Enums\UserType#415 (3) {
    public $key =>
    string(13) "Administrator"
    public $value =>
    int(0)
    public $description =>
    string(13) "Administrator"
  }
  'Moderator' =>
  class BenSampo\Enum\Tests\Enums\UserType#396 (3) {
    public $key =>
    string(9) "Moderator"
    public $value =>
    int(1)
    public $description =>
    string(9) "Moderator"
  }
  'Subscriber' =>
  class BenSampo\Enum\Tests\Enums\UserType#393 (3) {
    public $key =>
    string(10) "Subscriber"
    public $value =>
    int(2)
    public $description =>
    string(10) "Subscriber"
  }
  'SuperAdministrator' =>
  class BenSampo\Enum\Tests\Enums\UserType#102 (3) {
    public $key =>
    string(18) "SuperAdministrator"
    public $value =>
    int(3)
    public $description =>
    string(19) "Super administrator"
  }
}

静态 coerce(): ?Enum

如果存在,尝试使用给定值实例化一个新的枚举。如果不存在,则返回null。

UserType::coerce(0); // Returns instance of UserType with the value set to UserType::Administrator
UserType::coerce(99); // Returns null (not a valid enum value)