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

How to get all values of an enum in PHP?

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

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

enum Status
{
    case PAID;
    case Cancelled;
}

Status::cases();

案例方法将为每个值 return 一个带有枚举(UnitEnum 接口)的数组。

除了 UnitEnum::cases() 之外,您还可以将 ReflectionEnum 与此

一起使用
$reflection = new ReflectionEnum(Status::class);

$reflection->getCases();

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

需要值而不是枚举实例?

written a Composer package 为此,othyn/php-enum-enhancements,因为 UnitEnum::cases() 方法不是我要找的,因为 returns MySuperCoolEnum 实例而不是基础值作为它们的原始类型,这正是我想要的。

它是一种可以轻松添加到执行以下操作的任何枚举的特征:

  • 添加一个新的静态 UnitEnum::valueArray(): array 方法,returns 枚举中的所有值作为枚举值的相同类型数组

  • 添加一个新的静态 UnitEnum::valueList(string $separator = ', '): string 方法,returns 枚举中的所有值作为逗号分隔的列表字符串

其中为 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

Usage part of the package's README中还有更多示例。

对于基本枚举:

$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() 将 return:

Array
(
    [H] => Hearts
    [D] => Diamonds
    [C] => Clubs
    [S] => Spades
)