mindtwo / laravel-enum
Requires
- php: ~7.1
- hanneskod/classtools: ~1.0
- illuminate/support: 5.4.*|5.5.*|5.6.*|5.7.*|5.8.*|5.9.*|6.*|7.*
- zendframework/zend-code: ^3.3
Requires (Dev)
- laravel/framework: 7.*
- orchestra/testbench: ^5.0
This package is auto-updated.
Last update: 2020-09-21 16:11:16 UTC
README
关于 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"
实例属性
一旦你有了枚举实例,你可以将其key
、value
和description
作为属性访问。
$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)