Как получить все значения перечисления в 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"
]
**/