Enum

PHP Enum (Enumerations)

Examples

Specify the input enum type on the function parameters

enum Suit {
    case Clubs;
    case Diamonds;
    case Hearts;
    case Spades;
}

function pick_card(Suit $suit) {}

pick_card(Suit::Clubs);
pick_card(Suit::Diamonds);
pick_card(Suit::Hearts);
pick_card(Suit::Spades);

Return type

enum HTTPMethods: string {
    case GET = 'get';
    case POST = 'post';
}

Case-Sensitivity

enum CaseInSenSitive {
    case bAR;
    case Bar;
}

Class/object functions and instanceof

enum Suit {
    case Clubs;
    case Diamonds;
    case Hearts;
    case Spades;
}

gettype(Suit::Clubs); // "object"

is_object(Suit::Spades); // true
is_a(Suit::Clubs, Suit::class); // true

get_class(Suit::Clubs); // "Suit"
get_debug_type(Suit::Clubs); // "Suit"

Suit::Clubs instanceof Suit; // true
Suit::Clubs instanceof UnitEnum; // true
Suit::Clubs instanceof object; // false

Enums allow methods

enum HTTPStatus: int {
    case OK = 200;
    case ACCESS_DENIED = 403;
    case NOT_FOUND = 404;

    public function label(): string {
        return static::getLabel($this);
    }

    public static function getLabel(self $value): string {
        return match ($value) {
            HTTPStatus::OK => 'OK',
            HTTPStatus::ACCESS_DENIED => 'Access Denied',
            HTTPStatus::NOT_FOUND => 'Page Not Found',
        };
    }
}

echo HTTPStatus::ACCESS_DENIED->label(); // "Access Denied"
echo HTTPStatus::getLabel(HTTPStatus::ACCESS_DENIED); // "Access Denied"

Enums can implement interfaces

interface Foo {}
enum FooEnum implements Foo {}

Enums support property-less traits

trait NamedDocumentStatus {
    public function getStatusName(): string {}
}

enum DocumentStats {
    use NamedDocumentStatus;

    case DRAFT;
    case PUBLISHED;
}

Enum name and value properties

enum Suit: string {
    case Clubs = '♣';
    case Diamonds = '♦';
    case Hearts = '♥';
    case Spades = '♠';
}

echo Suit::Clubs->name; // "Clubs"
echo Suit::Clubs->value; // "♣"

Getting All Enum Values

enum Suit {
    case Clubs;
    case Diamonds;
    case Hearts;
    case Spades;
}

Suit::cases();
// [Suit::Clubs, Suit::Diamonds, Suit::Hearts, Suit::Spaces]

Getting Enum by a backed value

enum Suit: string {
    case Clubs = '♣';
    case Diamonds = '♦';
    case Hearts = '♥';
    case Spades = '♠';
}

$clubs = Suit::from('♥');

var_dump($clubs); // enum(Suit::Hearts)
echo $clubs->name; // "Hearts";
echo $clubs->value; // "♥"
enum Suit: string {
    case Clubs = '♣';
    case Diamonds = '♦';
    case Hearts = '♥';
    case Spades = '♠';
}

$clubs = Suit::tryFrom('not-existing');

var_dump($clubs); // null

Error Example

Associate values for each case, it must declare the scalar type

// ERROR
enum HTTPMethods {
    case GET = 'get';
    case POST = 'post';
}

Declares the scalar type of values, it must set a value for all cases

// ERROR
enum HTTPMethods: string {
    case GET;
    case POST;
}

Enums only support string and int scalar types

// ERROR
enum HTTPMethods: object {
    case GET = 'get';
    case POST = 'post';
}

Each case must be of the same type

// ERROR
enum HTTPMethods: int {
    case GET = 1;
    case POST = '2';
}

Must not contain duplicate cases

// ERROR
enum Test: string {
    case FOO = 'baz';
    case BAR = 'baz';
}

Enums must NOT contain properties

// Fatal error: Enums may not include properties in ... on line ...
enum Foo {
    private string $test;
    private static string $test2;
}

Enums CANNOT be extended, and must not inherit

// Parse error: syntax error, unexpected token "extends", expecting "{" in ... on line ...
enum Foo extends Bar {}

// Fatal error: Class Bar cannot extend final class Foo in ... on line ...
enum Foo {}
class Bar extends Foo {}

Enums as array keys

// ERROR
$list = [
    Status::DRAFT => 'draft',
    // …
];

Functions

enum_exists()

enum_exists(string $enum, bool $autoload = true): bool

if (enum_exists(Suit::class)) {
    $myclass = Suit::Hearts;
}

Classes vs Enums

Classes Enums
Syntax class Foo {} enum Foo {}
Properties
Static Properties
Methods
Static Methods
Autoloading
Instantiating: new Foo()
Implement interfaces
Inheritance: Foo extends Bar
Magic Constants: ::class, CLASS, etc.
Object Comparison Foo === Foo Not equal Equals
Traits Supports Supports without properties

Comparing Enum Values

new stdClass() === new stdClass(); // false
Suit::Hearts === Suit::Hearts; // true

Reference