如何在PHP中获取枚举的所有值?

s2j5cfk0  于 2023-02-07  发布在  PHP
关注(0)|答案(7)|浏览(167)

PHP 8.1即将发布,包括对枚举的支持。我测试了一些枚举功能,但没有找到很多关于它的文档。因此我的问题是:我如何得到一个枚举的所有值?

bttbmeg0

bttbmeg01#

对于基本枚举:

$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
)
de90aj5v

de90aj5v2#

经过一番研究,我发现the answer.你可以使用静态方法:cases().

enum Status
{
    case PAID;
    case Cancelled;
}

Status::cases();

cases方法将为每个值返回一个包含枚举(UnitEnum接口)的数组。

gajydyqb

gajydyqb3#

需要值而不需要枚举示例?

我用written a Composer package来表示othyn/php-enum-enhancements,因为UnitEnum::cases()方法不是我要找的,因为它返回一个MySuperCoolEnum示例的数组,而不是我想要的原始类型的底层值。
它是一个可以很容易地添加到任何枚举中的特性,该枚举执行以下操作:

  • 添加新的静态UnitEnum::valueArray(): array方法,该方法将枚举中的所有值作为类型相同的枚举值数组返回
  • 添加新的静态UnitEnum::valueList(string $separator = ', '): string方法,该方法将枚举中的所有值作为逗号分隔的列表字符串返回

其中,对于 normal 枚举,将生成以下内容:

<?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上工作!
在包的自述文件的用法部分有更多的例子。

lnlaulya

lnlaulya4#

除了UnitEnum::cases()之外,您还可以将ReflectionEnum与以下命令一起使用

$reflection = new ReflectionEnum(Status::class);

$reflection->getCases();

注意,在这两种情况下,您都不能获得枚举方法。但只要ReflectionEnum扩展ReflectionClass,您就可以使用其余的ReflectionClass方法,例如getMethods

of1yzvn4

of1yzvn45#

我认为最好的选择是使用一个特性。
例如:EnumsToArray.php

<?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";
}
tzcvj98z

tzcvj98z6#

我在我的项目中使用了以下内容;

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()获取列或值
我已经使用这段代码在一个表单select中轻松地foreach了它们

llew8vvj

llew8vvj7#

我把@Michael的一个小改动打包成了一个小包,因为我在多个项目中都需要它:
https://github.com/laracraft-tech/laravel-useful-traits#usefulenums

通过编写器安装

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]

相关问题