Start · Sprachen · PHP · Referenz · ReflectionEnum

ReflectionEnum

Enum

Ermöglicht die Reflexion eines PHP-Enums und liefert Informationen über dessen Fälle, Typen und Methoden.

seit PHP 8.1.0 Kategorie: oop

Signatur

class ReflectionEnum extends ReflectionClass implements Reflector

Beschreibung

ReflectionEnum erweitert ReflectionClass und stellt spezialisierte Methoden bereit, um zur Laufzeit detaillierte Informationen über ein Enum zu erhalten. Mit dieser Klasse lassen sich alle Enum-Cases auflisten, prüfen ob ein bestimmter Case existiert, den zugrundeliegenden Backing-Typ ermitteln und einzelne Cases als ReflectionEnumUnitCase- bzw. ReflectionEnumBackedCase-Objekte abrufen.

Besonders nützlich ist ReflectionEnum beim Erstellen generischer Bibliotheken, Serialisierungssysteme, Validierungsframeworks oder API-Dokumentationswerkzeuge, die Enums dynamisch verarbeiten müssen, ohne deren konkreten Typ zur Compile-Zeit zu kennen.

Während reine Enums (Pure Enums) nur einen Namen besitzen, haben Backed Enums zusätzlich einen skalaren Wert vom Typ string oder int. Die Methode getBackingType() gibt bei Backed Enums ein ReflectionNamedType-Objekt zurück, bei Pure Enums null. Mit isBacked() lässt sich dies bequem prüfen.

Da ReflectionEnum von ReflectionClass erbt, stehen auch alle Standard-Reflexionsmethoden wie getMethods(), getInterfaces() oder getAttributes() zur Verfügung.

Parameter

Name Typ Default Beschreibung
$objectOrName Pflicht object|string Entweder der vollqualifizierte Klassenname des Enums als string oder eine Instanz (ein Case) des Enums.

Beispiele

Backed Enum inspizieren und Cases auflisten

<?php
enum Status: string
{
    case Active   = 'active';
    case Inactive = 'inactive';
    case Pending  = 'pending';
}

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

echo 'Enum: ' . $ref->getName() . PHP_EOL;
echo 'Backed: ' . ($ref->isBacked() ? 'ja' : 'nein') . PHP_EOL;
echo 'Backing-Typ: ' . $ref->getBackingType() . PHP_EOL;

foreach ($ref->getCases() as $case) {
    /** @var ReflectionEnumBackedCase $case */
    echo sprintf(
        '  Case %-10s => %s%s',
        $case->getName(),
        $case->getBackingValue(),
        PHP_EOL
    );
}
Enum: Status Backed: ja Backing-Typ: string Case Active => active Case Inactive => inactive Case Pending => pending

Einzelnen Case prüfen und abrufen

<?php
enum Direction
{
    case North;
    case South;
    case East;
    case West;
}

$ref = new ReflectionEnum(Direction::class);

$caseName = 'North';
if ($ref->hasCase($caseName)) {
    $case = $ref->getCase($caseName);
    echo 'Gefundener Case: ' . $case->getName() . PHP_EOL;
    echo 'Wert: ';
    var_dump($case->getValue());
} else {
    echo 'Case nicht gefunden.' . PHP_EOL;
}
Gefundener Case: North Wert: enum(Direction::North)

Generische Funktion zur Enum-Validierung

<?php
enum Color: int
{
    case Red   = 1;
    case Green = 2;
    case Blue  = 3;
}

function isValidBackingValue(string $enumClass, mixed $value): bool
{
    $ref = new ReflectionEnum($enumClass);
    if (!$ref->isBacked()) {
        throw new InvalidArgumentException("$enumClass ist kein Backed Enum.");
    }
    foreach ($ref->getCases() as $case) {
        /** @var ReflectionEnumBackedCase $case */
        if ($case->getBackingValue() === $value) {
            return true;
        }
    }
    return false;
}

var_dump(isValidBackingValue(Color::class, 2));  // true
var_dump(isValidBackingValue(Color::class, 99)); // false
bool(true) bool(false)

// Wichtig · Fallstricke

Vererbungshierarchie: ReflectionEnum erbt von ReflectionClass. Das bedeutet, dass Methoden wie isAbstract() oder getParentClass() zwar verfügbar, aber für Enums nicht sinnvoll sind, da Enums weder abstrakt noch erweiterbar sind.

Unterschied zu ReflectionClass: Wird ein Enum-Name an new ReflectionClass() übergeben, erhält man ebenfalls ein Reflexionsobjekt, allerdings ohne die enum-spezifischen Methoden getCases(), getCase(), hasCase() und getBackingType(). Für Enum-Reflexion sollte daher stets ReflectionEnum bevorzugt werden.

Pure vs. Backed Enums: Bei Pure Enums gibt getBackingType() null zurück, und getCases() liefert ReflectionEnumUnitCase-Objekte. Bei Backed Enums liefert getCases() ReflectionEnumBackedCase-Objekte mit der zusätzlichen Methode getBackingValue().