Как получить все значения перечисления в PHP?

PHP 8.1 почти готов, включая поддержку Enumerations. Я тестировал некоторые функции перечисления и не мог найти по нему много документации. Отсюда мой вопрос: как мне получить все значения перечисления?

8 ответов

Для основных перечислений:

      $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();

Метод case вернет массив с перечислением ( UnitEnum интерфейс) для каждого значения.

Нужны значения, а не экземпляры Enum?

Я написал для этого пакет Composer , othyn/php-enum-enhancements, как UnitEnum::cases()метод был не тем, что я искал, так как он возвращает массив MySuperCoolEnumэкземпляры вместо базовых значений в качестве их необработанного типа, чего я и хотел.

Это черта, которую можно легко добавить к любому перечислению, которое делает следующее:

  • Добавляет новый статический UnitEnum::valueArray(): arrayметод, который возвращает все значения в Enum в виде равнотипного массива значений Enum.

  • Добавляет новый статический UnitEnum::valueList(string $separator = ', '): stringметод, который возвращает все значения в Enum в виде строки списка, разделенной запятыми

В котором для обычных 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"

... и следующее для Backed Enum, следующее является 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::casses() вы можете использовать с этим

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

$reflection->getCases();

обратите внимание, что в обоих случаях вы не сможете получить методы перечисления. но пока ReflectionEnum расширяет ReflectionClass поэтому вы можете использовать остальные методы ReflectionClass, такие как getMethods

Я использовал следующее в своем проекте;

      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

Я завернул немного измененный подход от @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]

Я думаю, что лучший вариант — использовать черту для этого.

Например: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";
}

Другой способ получить только значения перечисления — следовать этому подходу:

      
<?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"
]
**/
Другие вопросы по тегам