¿Cómo obtener todos los valores de una enumeración en PHP?

4 minutos de lectura

PHP 8.1 está a punto de ser lanzado, incluido el soporte para Enumeraciones. Estaba probando parte de la funcionalidad de enumeración y no pude encontrar mucha documentación al respecto. De ahí mi pregunta: ¿cómo obtengo todos los valores de una enumeración?

Avatar de usuario de Michael
Miguel

Para enumeraciones básicas:

$suits = array_column(Suit::cases(), 'name');

Para enumeraciones respaldadas donde desea los valores:

$suits = array_column(Suit::cases(), 'value');

A continuación, podría hacer algo como esto:

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() regresará:

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

  • Gracias por esto. volteé array_combine(self::names(), self::values()). Tener los nombres como claves de matriz me parece más natural.

    – Pete

    2 de junio a las 3:06

Avatar de usuario de Dees Oomens
Dees Oomens

Después de algunas investigaciones encontré la respuesta. Puedes usar el método estático: cases().

enum Status
{
    case PAID;
    case Cancelled;
}

Status::cases();

El método de casos devolverá una matriz con una enumeración (UnitEnum interfaz) para cada valor.

  • también puede leer acerca de los métodos de enumeración para PHP 8.1 en el Enlace

    – timnavegar

    23 de noviembre de 2021 a las 12:52


Avatar de usuario de Othyn
Othyn

¿Necesita los valores y no las instancias de Enum?

He escrito un paquete Composer para esto, othyn/php-enum-enhancementscomo el UnitEnum::cases() El método no era lo que estaba buscando, ya que devuelve una matriz de MySuperCoolEnum instancias en lugar de los valores subyacentes como su tipo sin procesar, que es lo que quería.

Es un rasgo que se puede agregar fácilmente a cualquier enumeración que haga lo siguiente:

  • Agrega una nueva estática UnitEnum::valueArray(): array método que devuelve todos los valores dentro de un Enum como una matriz de valores de Enum del mismo tipo

  • Agrega una nueva estática UnitEnum::valueList(string $separator=", "): string método que devuelve todos los valores dentro de un Enum como una cadena de lista separada por comas

En el que se produce lo siguiente para normal enumeraciones:

<?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"

… y lo siguiente para Backed Enum’s, siendo lo siguiente un string ejemplo:

<?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"

… y sí, funciona en int¡también!

Hay más ejemplos en el Uso parte del README del paquete.

avatar de usuario de hassan
Hasan

Además de UnitEnum::cases() puedes usar ReflectionEnum con este

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

$reflection->getCases();

tenga en cuenta que en ambos casos no podrá obtener los métodos de enumeración. pero mientras el ReflectionEnum está extendiendo el ReflectionClass para que pueda usar el resto de los métodos de ReflectionClass como getMethods

Creo que la mejor opción es usar un rasgo para eso.

Por ejemplo: EnumsToArray.php

<?php

namespace App\Traits;

trait EnumsToArray {
    public static function toArray(): array {
        return array_map(
            fn(self $enum) => $enum->value, 
            self::cases()
        );
    }
}

Y más tarde, en tu enumeración deberías tener:

use App\Traits\EnumsToArray;

Enum Currency: string {
    use EnumsToArray;
    
    case DOLLAR = "usd";
    case EURO = "eur";
}

Avatar de usuario de Maarten
Marten

He usado lo siguiente en mi proyecto;

public static function toAssociativeArray(): array
{
    foreach(self::cases() as $case) {
        $array[$case->value] = $case->name;
    }
    return $array;
}

Lo que da como resultado una matriz asociativa como esta;

usando cadenas como valores

enum DiaryRole: string
{
    case DANGER  = 'red';
    case WARNING = 'yellow';
    case SAFE    = 'green';
}

$array = [
    'red'    => 'DANGER',
    'yellow' => 'WARNING',
    'green'  => 'SAFE'
];

o cuando se usan números enteros como valores

enum DiaryRole: int
{
    case DANGER  = 1;
    case WARNING = 2;
    case SAFE    = 3;
}

$array = [
    1 => 'DANGER',
    2 => 'WARNING',
    3 => 'SAFE'
];

Ahora puede usar la matriz para obtener cualquier información que necesite, y puede obtener solo las columnas o valores usando array_keys() o array_values()

He usado este código para buscar fácilmente a través de ellos en una selección de formulario

¿Ha sido útil esta solución?