Enums

An enum (enumeration) declares a fixed set of possible values for a type, called cases. A pure enum case has no value of its own — it is simply a distinct, comparable singleton instance, referred to as EnumName::CaseName.

<?php
enum Suit {
  case Hearts;
  case Diamonds;
  case Clubs;
  case Spades;
}

$suit = Suit::Hearts;
echo $suit->name, "\n";
var_dump($suit === Suit::Hearts);
?>

Hearts bool(true)
A backed enum gives every case a scalar value (all int, or all string), accessible through the ->value property. EnumName::from($value) looks up the matching case, throwing a \ValueError if none matches. EnumName::tryFrom($value) does the same but returns null instead of throwing. EnumName::cases() returns every case as an array, in declaration order.

<?php
enum Suit: string {
  case Hearts = 'H';
  case Diamonds = 'D';
  case Clubs = 'C';
  case Spades = 'S';
}

echo Suit::Hearts->value, "\n";
echo Suit::from('D')->name, "\n";
var_dump(Suit::tryFrom('X'));

try {
  Suit::from('X');
} catch (\ValueError $e) {
  echo $e->getMessage(), "\n";
}

foreach (Suit::cases() as $case) {
  echo $case->name, ' = ', $case->value, "\n";
}
?>

H Diamonds NULL "X" is not a valid backing value for enum Suit Hearts = H Diamonds = D Clubs = C Spades = S
An enum can declare methods just like a class, and can implement an interface. $this inside a method refers to the current case, so a match on $this is a common way to attach per-case behaviour.

<?php
interface HasColor {
  function color(): string;
}

enum Suit: string implements HasColor {
  case Hearts = 'H';
  case Diamonds = 'D';
  case Clubs = 'C';
  case Spades = 'S';

  public function color(): string {
    return match ($this) {
      Suit::Hearts, Suit::Diamonds => 'Red',
      Suit::Clubs, Suit::Spades => 'Black',
    };
  }
}

foreach (Suit::cases() as $case) {
  echo "{$case->name}: {$case->color()}\n";
}
?>

Hearts: Red Diamonds: Red Clubs: Black Spades: Black
An enum may also declare constants and static methods, but it cannot have regular (instance) properties, and cannot be instantiated with new or extended with extends.