PHP 8.1即将发布,支持枚举。 我正在测试一些枚举功能,但找不到太多关于它的文档。 因此我的问题是:如何获取枚举的所有值?
对于基本枚举:
$suits = array_column(Suit::cases(), 'name');
对于需要返回值的支持枚举类型:
$suits = array_column(Suit::cases(), 'value');
你可以像这样做: 然后你可以像这样做:
trait EnumToArray
{
public static function names(): array
{
return array_column(self::cases(), 'name');
}
public static function values(): array
{
return array_column(self::cases(), 'value');
}
public static function array(): array
{
return array_combine(self::values(), self::names());
}
}
enum Suit: string
{
use EnumToArray;
case Hearts = 'H';
case Diamonds = 'D';
case Clubs = 'C';
case Spades = 'S';
}
Suit::array()
将返回:
Array
(
[H] => Hearts
[D] => Diamonds
[C] => Clubs
[S] => Spades
)
经过一些研究,我找到了答案。你可以使用静态方法:cases()
。
enum Status
{
case PAID;
case Cancelled;
}
Status::cases();
cases方法将返回一个数组,其中包含每个值的枚举(UnitEnum
接口)。
需要值而不是枚举实例吗?
我为此编写了一个 Composer 包 othyn/php-enum-enhancements
,因为 UnitEnum::cases()
方法并不是我想要的,该方法返回一个 MySuperCoolEnum
实例的数组,而不是它们底层的原始类型值,这正是我想要的。
这是一个可以轻松添加到任何枚举中的 trait,它执行以下操作:
添加一个新的静态方法 UnitEnum::valueArray(): array
,将 Enum 中的所有值作为同类型的数组 Enum 值返回
添加一个新的静态方法 UnitEnum::valueList(string $separator = ', '): string
,将 Enum 中的所有值作为逗号分隔的列表字符串返回
对于常规 枚举,它将产生以下结果:
<?php
namespace App\Enums;
use Othyn\PhpEnumEnhancements\Traits\EnumEnhancements;
enum TestEnum
{
use EnumEnhancements;
case Alpha;
case Bravo;
case Charlie;
case Delta;
case Echo;
}
var_dump(TestEnum::valueArray());
// Results in the following being printed:
// array(5) {
// [0]=>
// string(5) "Alpha"
// [1]=>
// string(5) "Bravo"
// [2]=>
// string(7) "Charlie"
// [3]=>
// string(5) "Delta"
// [4]=>
// string(4) "Echo"
// }
var_dump(TestEnum::valueList());
// Results in the following being printed:
// string(34) "Alpha, Bravo, Charlie, Delta, Echo"
var_dump(TestEnum::valueList(separator: ':'));
// Results in the following being printed:
// string(30) "Alpha:Bravo:Charlie:Delta:Echo"
...而对于后备枚举,以下是一个string
示例:
<?php
namespace App\Enums;
use Othyn\PhpEnumEnhancements\Traits\EnumEnhancements;
enum TestStringBackedEnum: string
{
use EnumEnhancements;
case Alpha = 'alpha';
case Bravo = 'bravo';
case Charlie = 'charlie';
case Delta = 'delta';
case Echo = 'echo';
}
var_dump(TestStringBackedEnum::valueArray());
// Results in the following being printed:
// array(5) {
// [0]=>
// string(5) "alpha"
// [1]=>
// string(5) "bravo"
// [2]=>
// string(7) "charlie"
// [3]=>
// string(5) "delta"
// [4]=>
// string(4) "echo"
// }
var_dump(TestStringBackedEnum::valueList());
// Results in the following being printed:
// string(34) "alpha, bravo, charlie, delta, echo"
var_dump(TestStringBackedEnum::valueList(separator: ':'));
// Results in the following being printed:
// string(30) "alpha:bravo:charlie:delta:echo"
...而且它也适用于int
!
在软件包的README的使用部分中有更多示例。
UnitEnum::cases()
外,您还可以使用 ReflectionEnum
。$reflection = new ReflectionEnum(Status::class);
$reflection->getCases();
ReflectionEnum
扩展了 ReflectionClass
,您就可以使用其余的 ReflectionClass 方法,例如 getMethods
。Status::cases()
更好吗? - nickdnk在我的项目中,我使用了以下内容:
public static function toAssociativeArray(): array
{
foreach(self::cases() as $case) {
$array[$case->value] = $case->name;
}
return $array;
}
enum DiaryRole: string
{
case DANGER = 'red';
case WARNING = 'yellow';
case SAFE = 'green';
}
$array = [
'red' => 'DANGER',
'yellow' => 'WARNING',
'green' => 'SAFE'
];
当使用整数作为值时
enum DiaryRole: int
{
case DANGER = 1;
case WARNING = 2;
case SAFE = 3;
}
$array = [
1 => 'DANGER',
2 => 'WARNING',
3 => 'SAFE'
];
array_keys()
或array_values()
函数来获取列或值。
我已经使用此代码轻松地在表单选择器中遍历它们。
<?php
namespace App\Traits;
trait EnumsToArray {
public static function toArray(): array {
return array_map(
fn(self $enum) => $enum->value,
self::cases()
);
}
}
后来,在您的枚举中,您应该有:
use App\Traits\EnumsToArray;
Enum Currency: string {
use EnumsToArray;
case DOLLAR = "usd";
case EURO = "eur";
}
我将@Michael稍作修改的方法封装成一个小包,因为我需要在多个项目中使用:
https://github.com/laracraft-tech/laravel-useful-traits#usefulenums
通过 Composer 安装:
composer require laracraft-tech/laravel-useful-traits
它是这样工作的:
use LaracraftTech\LaravelUsefulTraits\UsefulEnums;
enum PaymentType: int
{
use UsefulEnums;
case Pending = 1;
case Failed = 2;
case Success = 3;
}
PaymentType::names(); // return ['Pending', 'Failed', 'Success']
PaymentType::values(); // return [1, 2, 3]
PaymentType::array(); // return ['Pending' => 1, 'Failed' => 2, 'Success' => 3]
通过以下方法获得枚举值的另一种方式:
<?php namespace JCKCon\Enums;
enum UsersPermissions: string
{
case CREATE = "create";
case UPDATE = "update";
case DELETE = "delete";
case VIEW = "view";
case PUBLISH = "publish";
public static function toArray()
{
$values = [];
foreach (self::cases() as $props) {
array_push($values, $props->value);
}
return $values;
}
}
dd(UsersPermissions::toArray());
/**
array:5 [
0 => "create"
1 => "update"
2 => "delete"
3 => "view"
4 => "publish"
]
**/
value
在此情况下不是一个已定义的属性。您应该使用$props->name
。另外,我会将toArray
方法重写为:return array_map(fn($case) => $case->name, self::cases());
。 - Cornel Raiu
array_combine(self::names(), self::values())
。将名称作为数组键更符合我的直觉。 - MaksidacontainsValue()
函数,返回\in_array($value, self::values(), true);
。 - undefinedtryFrom
来实现这个功能:https://www.php.net/manual/en/backedenum.tryfrom.php - undefined