80

PHP 8.1 adds support for Enumerations. I was testing some of the enum functionality and couldn't find much documentation about it.

How do I get all values of an enum?

9 Answers 9

192

For basic enums:

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

For backed enums where you want the values:

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

You could then do something like this:

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

Array
(
    [H] => Hearts
    [D] => Diamonds
    [C] => Clubs
    [S] => Spades
)
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for this. I flipped array_combine(self::names(), self::values()). Having the names as array keys feels more natural to me.
Thx, I added a containsValue() function return \in_array($value, self::values(), true);
@v.nivuahc You can just use tryFrom for that: php.net/manual/en/backedenum.tryfrom.php
Awesome! that was really helpful! The array() method can also be written with array_column and the 3rd param for index_key column, like this: array_column(self::cases(), 'value', 'name') and will result in an assoc array with names as keys.
48

After some research I found the answer. You can use the static method: cases().

enum Status
{
    case PAID;
    case Cancelled;
}

Status::cases();

The cases method will return an array with an enum (UnitEnum interface) for each value.

2 Comments

you can also read about enum methods for PHP 8.1 at the link
This does not answer the question. The question was how to get all the values of a BackedEnum.
7

Need the values and not Enum instances?

I've written a Composer package for this, othyn/php-enum-enhancements, as the UnitEnum::cases() method wasn't what I was looking for, as that returns an array of MySuperCoolEnum instances instead of the underlying values as their raw type, which is what I wanted.

Its a trait that can be easily added to any enum that does the following:

  • Adds a new static UnitEnum::valueArray(): array method that returns all values within an Enum as an equally typed array of Enum values

  • Adds a new static UnitEnum::valueList(string $separator = ', '): string method that returns all values within an Enum as a comma separated list string

In which produces the following for normal Enum's:

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

... and the following for Backed Enum's, the following being a string example:

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

... and yes it works on int's too!

There are more examples in the Usage part of the package's README.

Comments

4

In addition to UnitEnum::cases() you can use ReflectionEnum with this

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

$reflection->getCases();

note that in both cases you will not be able to get the enum methods. but as long as the ReflectionEnum is extending the ReflectionClass so you can use the rest of ReflectionClass methods such as getMethods

2 Comments

This is a lot better than the accepted answer. I prefer Reflection for all things classes, interfaces, enums..
How is this better than just Status::cases()?
4

I have used the following in my project;

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

Which results in an associative array like this;

using strings as values

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

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

or when using integers as values

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

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

You can now use the array to get any information you need, and you can get only the columns or values using array_keys() or array_values()

I have used this code to easily foreach through them in a form select

Comments

3

Another way to get just the values of the enum is by following this approach:


<?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"
]
**/

2 Comments

value is not a defined property in this case. You should use $props->name. Also, I would rewrite the the toArray method to this: return array_map(fn($case) => $case->name, self::cases());.
Ignore this part value is not a defined property in this case. You should use $props->name. I didn't pay attention to it to see it's a backed enum. Whoops
3

The simplest one-liner:

enum Suit: string
{
    case Hearts = 'H';
    case Diamonds = 'D';
    case Clubs = 'C';
    case Spades = 'S';
}
array_column(Suit::cases(), 'name', 'value');

It would return:

[
    "H" => "Hearts",
    "D" => "Diamonds",
    "C" => "Clubs",
    "S" => "Spades"
]

If you need to swap keys and values:

array_column(Suit::cases(), 'value', 'name');
[
    "Hearts" => "H",
    "Diamonds" => "D",
    "Clubs" => "C",
    "Spades" => "S"
]

Comments

2

I think the best options is using a trait for that.

For example: EnumsToArray.php

<?php

namespace App\Traits;

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

And later, in you enum you should have:

use App\Traits\EnumsToArray;

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

Comments

2

I wrapped a slitly changed approach from @Michael up in a small package, cause I needed it in multiple projects:

https://github.com/laracraft-tech/laravel-useful-traits#usefulenums

Install via composer:

composer require laracraft-tech/laravel-useful-traits

This is how it is working:

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]

1 Comment

This is great. Does it work also on casts? like protected function casts(): array { return [ 'paymentType' => PaymentType::class, ]; }

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.