biiiiiigmonster / laravel-enum
基于 PHP 8.1 的 Laravel 枚举助手
Requires
- laminas/laminas-code: ^4.10
- laravel/framework: >=10
Requires (Dev)
- laravel/pint: ^1.0
- nunomaduro/larastan: ^2.0.1
- orchestra/testbench: ^8.0
- pestphp/pest: ^2.0
- pestphp/pest-plugin-laravel: ^2.0
- phpstan/extension-installer: ^1.1
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-phpunit: ^1.0
This package is auto-updated.
Last update: 2024-09-09 23:06:22 UTC
README
基于 PHP 8.1 枚举特性的 Laravel 10 枚举助手。
安装
您可以通过 composer 安装此包。
composer require biiiiiigmonster/laravel-enum
使用方法
要开始使用,枚举通常位于 app\Enums 目录。您可以使用 make:enum Artisan 命令生成一个新的枚举。
php artisan make:enum TaskStatus
如果您想生成一个 支持值的枚举,您可以使用带有 --type 选项的 make:enum Artisan 命令。
php artisan make:enum TaskStatus --type=int
同时,您也可以将 trait 应用到现有的枚举上。
use BiiiiiigMonster\LaravelEnum\Concerns\EnumTraits; // pure enum. enum Role { use EnumTraits; case ADMINISTRATOR; case SUBSCRIBER; case GUEST; } // backed enum. enum TaskStatus: int { use EnumTraits; case INCOMPLETE = 0; case COMPLETED = 1; case CANCELED = 2; }
可调用的
此助手让您可以通过“调用”枚举来获取其原始值或纯枚举的名称——无论是静态地(MyEnum::FOO() 代替 MyEnum::FOO),还是作为实例($enum())。
这样,您可以使用枚举作为数组键。
'statuses' => [ TaskStatus::INCOMPLETE() => ['some configuration'], TaskStatus::COMPLETED() => ['other configuration'], ],
或访问任何其他用例的基础原始值。
public function updateStatus(int $status): void; $task->updateStatus(TaskStatus::COMPLETED());
主要观点:这一切都不需要为每个元素添加 ->value。
TaskStatus::CANCELED; // => TaskStatus instance TaskStatus::CANCELED(); // => 2
使用静态调用获取原始值
TaskStatus::INCOMPLETE(); // 0 TaskStatus::COMPLETED(); // 1 TaskStatus::CANCELED(); // 2 Role::ADMINISTRATOR(); // 'ADMINISTRATOR' Role::SUBSCRIBER(); // 'SUBSCRIBER' Role::GUEST(); // 'GUEST'
调用实例以获取原始值
public function updateStatus(TaskStatus $status, Role $role) { $this->record->setStatus($status(), $role()); }
增强
助手提供许多静态方法,以增强您使用枚举的体验。
名称
此助手返回枚举中的情况 名称 列表。
TaskStatus::names(); // ['INCOMPLETE', 'COMPLETED', 'CANCELED'] Role::names(); // ['ADMINISTRATOR', 'SUBSCRIBER', 'GUEST']
值
此助手返回支持值的枚举的情况 值 列表,或纯枚举的情况 名称 列表(使此函数与纯枚举的 ::names() 函数等效)。
TaskStatus::values(); // [0, 1, 2] Role::values(); // ['ADMINISTRATOR', 'SUBSCRIBER', 'GUEST']
选项
此助手返回一个数组,键是每个实例调用 () 返回的值,值是实例 ->label() 返回的值。
TaskStatus::options(); /* [ 0 => 'Incomplete', 1 => 'Completed', 2 => 'Canceled' ] */ Role::options(); /* [ 'ADMINISTRATOR' => 'Administrator', 'SUBSCRIBER' => 'Subscriber', 'GUEST' => 'Guest' ] */
表格
此助手返回每个实例的情况映射数组列表,如果实例附加了扩展 Meta 的属性,映射数组将包含更多内容。
TaskStatus::tables(); /* [ ['name' => 'INCOMPLETE', 'value' => 0], ['name' => 'COMPLETED', 'value' => 1], ['name' => 'CANCELED', 'value' => 2] ] */ Role::tables(); /* [ ['name' => 'ADMINISTRATOR'], ['name' => 'SUBSCRIBER'], ['name' => 'GUEST'] ] */
从
此助手将 from() 和 tryFrom() 添加到纯枚举,并将 fromName() 和 tryFromName() 添加到所有枚举。
重要说明:
BackedEnum实例已经实现了自己的from()和tryFrom()方法,不会被此 trait 覆盖。在BackedEnum中尝试覆盖这些方法会导致致命错误。- 纯枚举只有命名情况而没有值,因此
from()和tryFrom()方法在功能上等效于fromName()和tryFromName()。
使用 from() 方法
Role::from('ADMINISTRATOR'); // Role::ADMINISTRATOR Role::from('NOBODY'); // Error: ValueError
使用 tryFrom() 方法
Role::tryFrom('GUEST'); // Role::GUEST Role::tryFrom('NEVER'); // null
使用 fromName() 方法
TaskStatus::fromName('INCOMPLETE'); // TaskStatus::INCOMPLETE TaskStatus::fromName('MISSING'); // Error: ValueError Role::fromName('SUBSCRIBER'); // Role::SUBSCRIBER Role::fromName('HACKER'); // Error: ValueError
使用 tryFromName() 方法
TaskStatus::tryFromName('COMPLETED'); // TaskStatus::COMPLETED TaskStatus::tryFromName('NOTHING'); // null Role::tryFromName('GUEST'); // Role::GUEST Role::tryFromName('TESTER'); // null
随机
此助手返回通过随机选择的实例。
TaskStatus::random(); // TaskStatus::COMPLETED Role::random(); // Role::GUEST
默认情况
有时您可能需要为枚举指定默认情况,这很简单:只需将 #[DefaultCase] 属性附加到情况即可。
use BiiiiiigMonster\LaravelEnum\Attributes\DefaultCase; use BiiiiiigMonster\LaravelEnum\Concerns\EnumTraits; enum Role { use EnumTraits; #[DefaultCase] case ADMIN; case GUEST; }
然后使用 ::default() 静态方法获取此情况实例。
Role::default(); // Role::ADMIN Role::ADMIN->isDefault(); // true
元数据
此功能允许您向枚举情况添加元数据,它通过属性的方式使用。
use BiiiiiigMonster\LaravelEnum\Concerns\EnumTraits; use App\Enums\Metas\{Description, Color}; enum TaskStatus: int { use EnumTraits; #[Description('Incomplete Task')] #[Color('red')] case INCOMPLETE = 0; #[Description('Completed Task')] #[Color('green')] case COMPLETED = 1; #[Description('Canceled Task')] #[Color('gray')] case CANCELED = 2; }
创建元属性
要生成新的元属性,您可以使用 make:enumMeta Artisan 命令。
php artisan make:enumMeta Color
元属性需要作为一个属性存在。
use BiiiiiigMonster\LaravelEnum\Concerns\Meta; use Attribute; #[Attribute] class Color extends Meta {} #[Attribute] class Description extends Meta {}
在属性中,您可以自定义一些内容。例如,您可能想使用与类名派生的不同方法名(默认情况下 Description 变为 description())。为此,请在元数据上定义静态属性 alias。
#[Attribute] class Description extends Meta { public static string $alias = 'note'; }
使用上面的代码,案例的 ->description() 将作为 ->note() 可访问。
您还可以自定义传递的值。例如,要包装颜色名称如 text-{$color}-500,您需要添加以下 transform() 方法。
#[Attribute] class Color extends Meta { protected function transform(mixed $value): string { return "text-{$value}-500"; } }
现在返回的颜色将被正确转换。
TaskStatus::COMPLETED->color(); // 'text-green-500'
访问元数据
通过访问属性方法名称,您可以获取元数据值。
TaskStatus::INCOMPLETE->description(); // 'Incomplete Task' TaskStatus::COMPLETED->color(); // 'green'
此外,::tables() 静态方法可以返回每个实例上的所有元属性映射。
$tables = TaskStatus::tables(); // $tables [ [ 'name' => 'INCOMPLETE', 'value' => 0, 'description' => 'Incomplete Task', 'color' => 'red' ], [ 'name' => 'COMPLETED', 'value' => 1, 'description' => 'Completed Task', 'color' => 'green' ], [ 'name' => 'CANCELED', 'value' => 2, 'description' => 'Canceled Task', 'color' => 'gray' ] ]
使用 fromMeta() 方法
同样,您也可以通过元实例获取枚举案例实例。
$green = Color::make('green');// new Color('green'); $blue = Color::make('blue');// new Color('blue'); TaskStatus::fromMeta($green); // TaskStatus::COMPLETED TaskStatus::fromMeta($blue); // Error: ValueError
使用 tryFromMeta() 方法
TaskStatus::tryFromMeta($green); // TaskStatus::COMPLETED TaskStatus::tryFromMeta($blue); // null
验证
通常,我们需要限制您应用程序的传入数据到指定的枚举,Laravel 提供了基本规则,但这里我们已经完善了它。
数组验证
您可以使用 'array' 语法规则。
枚举
验证一个参数是否是给定枚举的实例,它与 枚举规则 类似,并支持纯枚举。
use BiiiiiigMonster\LaravelEnum\Rules\Enum; public function store(Request $request) { $this->validate($request, [ 'status' => ['required', new Enum(TaskStatus::class)], 'role' => ['required', new Enum(Role::class)], ]); }
枚举元数据
此外,验证一个参数是否是给定枚举中给定元数据的实例。
use BiiiiiigMonster\LaravelEnum\Rules\EnumMeta; public function store(Request $request) { $this->validate($request, [ 'color' => ['required', new EnumMeta(TaskStatus::class, Color::class)], ]); }
EnumMeta 规则接受两个参数,第一个是给定的枚举,第二个是给定的元数据,如果参数名称与元数据方法名称相同,则可以省略。
'color' => ['required', new EnumMeta(TaskStatus::class)],
管道验证
您也可以使用 'pipe' 语法规则。
- enumerate: enum_class
- enum_meta: enum_class,[meta_attribute]
'status' => 'required|enumerate:' . TaskStatus::class, 'color' => 'required|enum_meta:' . TaskStatus::class . ',' . Color::class,
验证消息
如果需要,您可以在验证失败时修改错误消息。
运行以下命令将语言文件发布到您的 lang 文件夹
php artisan vendor:publish --provider="BiiiiiigMonster\LaravelEnum\EnumServiceProvider" --tag="translations"
本地化
标签
枚举实例是描述性的,我们已经添加了翻译功能。您可以使用 Laravel 内置的 本地化 功能翻译枚举实例 ->label() 方法返回的字符串。
为您的每个受支持语言添加一个新的 enums.php 键文件。在这个例子中,有一个英文和一个西班牙语。
// lang/en/enums.php <?php declare(strict_types=1); use App\Enums\TaskStatus; return [ TaskStatus::class => [ TaskStatus::INCOMPLETE() => 'Incomplete', TaskStatus::COMPLETED() => 'Completed', TaskStatus::CANCELED() => 'Canceled', ], ];
// lang/es/enums.php <?php declare(strict_types=1); use App\Enums\TaskStatus; return [ TaskStatus::class => [ TaskStatus::INCOMPLETE() => 'Incompleto', TaskStatus::COMPLETED() => 'Completo', TaskStatus::CANCELED() => 'Cancelación', ], ];
现在,您只需要确保您的枚举实现了如以下示例所示的 Localizable 接口。
use BiiiiiigMonster\LaravelEnum\Concerns\EnumTraits; use BiiiiiigMonster\LaravelEnum\Contracts\Localizable; enum TaskStatus: int implements Localizable { use EnumTraits; // ... }
或者,当使用 make:enum Artisan 命令创建时,添加 --local 选项。
php artisan make:enum TaskStatus --local
现在,->label() 方法将查找本地化文件中的值
// en/enums.php TaskStatus::CANCELED->label();// 'Canceled' // es/enums.php TaskStatus::CANCELED->label();// 'Cancelación'
并且 ::options() 静态方法返回的数组值也将本地化。
// en/enums.php TaskStatus::options();// [0 => 'Incomplete', 1 => 'Completed', 2 => 'Canceled'] // es/enums.php TaskStatus::options();// [0 => 'Incompleto', 1 => 'Completo', 2 => 'Cancelación']
Artisan 命令
如果您希望您的 IDE 自动完成静态实例辅助工具,您可以通过 artisan 命令生成 PHPDoc 注释。
默认情况下,app/Enums 中的所有 Enums 都将被注释(您可以通过传递路径到 --folder 来更改文件夹)。
php artisan enum:phpdoc
此外,您也可以通过指定类名来注释单个类。
php artisan enum:phpdoc "App\Enums\TaskStatus"
use BiiiiiigMonster\LaravelEnum\Concerns\EnumTraits; use App\Enums\Metas\{Description, Color}; /** * @method static int INCOMPLETE() * @method static int COMPLETED() * @method static int CANCELED() * @method mixed description() * @method mixed color() */ enum TaskStatus: int { use EnumTraits; // ... }
测试
composer test
变更日志
有关最近更改的更多信息,请参阅 CHANGELOG。
参考
许可
MIT 许可证 (MIT)。有关更多信息,请参阅 许可文件。