Ein PHP-Enum (PHP 8.1+) definiert einen Typ mit einer festen Menge möglicher Werte, seinen Cases: enum Status { case Active; case Banned; }. Du verwendest einen Case als Status::Active, und ein Parameter vom Typ Status akzeptiert nichts anderes. Ein Backed Enum, enum Status: string, gibt jedem Case außerdem einen Wert, den du speichern und mit Status::from() zurückwandeln kannst.
Vor Enums war dasselbe eine Liste von String-Konstanten, und nichts hielt einen Tippfehler wie 'actve' davon ab, in der Datenbank zu landen. Mit Status als Parametertyp lassen sich nur die drei Cases übergeben.
Pure Enums und Backed Enums
Ein Pure Enum hat Cases, die nur Namen sind. Ein Backed Enum deklariert nach dem Namen einen Typ, int oder string, und jeder Case muss dann einen eindeutigen Wert dieses Typs haben. Jeder Case hat ->name; nur Backed Cases haben ->value.
Wähl ein Backed Enum, sobald der Wert das Programm verlässt: eine Datenbankspalte, eine URL, ein Formularfeld, JSON. Wähl ein Pure Enum für Werte, die nur im Code existieren, etwa den Zustand eines Parsers.
Einen Wert mit from() und tryFrom() umwandeln
Backed Enums bekommen zwei statische Methoden, um einen gespeicherten Wert wieder in einen Case zu verwandeln. from() wirft bei einem unbekannten Wert einen ValueError; tryFrom() liefert null, was gut zu ?? für einen Standardwert passt:
Verwende tryFrom() für alles, was ein Nutzer geschickt hat, und from() für Werte, die dein eigener Code geschrieben hat, wo ein unbekannter Wert einen Bug bedeutet, von dem du erfahren willst. Das Argument folgt den normalen Regeln für Parametertypen: Bei einem int-Enum liefert Priority::from('5') im Standardmodus Priority::Normal, weil '5' zuerst in 5 umgewandelt wird, Priority::from('5x') ist ein TypeError, und unter declare(strict_types=1) ist jeder String ein TypeError. Das gilt auch für tryFrom(): Priority::tryFrom('abc') wirft, statt null zu liefern, also prüfst du Formulareingaben für ein int-Enum vorher mit filter_var($raw, FILTER_VALIDATE_INT).
Alle Cases mit cases() auflisten
Enum::cases() liefert ein Array mit jedem Case, in der Reihenfolge der Deklaration. So baust du ein Dropdown, validierst eine Liste oder holst alle Werte mit array_column:
Führe es aus, wähle einen Tarif und klicke auf Choose: Dasselbe Skript läuft erneut, mit gefülltem $_POST['plan'], und tryFrom() macht aus dem gesendeten String wieder einen Plan-Case. Ein gefälschter Wert wie plan=gold ergibt null, und keine Option ist ausgewählt.
Enum-Methoden, Konstanten und Interfaces
Enums können Methoden, statische Methoden und Konstanten haben und Interfaces implementieren. In einer Methode ist $this der aktuelle Case, und deshalb ist match ($this) der natürliche Weg, jedem Case Daten zuzuordnen. Was ein Enum nicht haben kann, sind Eigenschaften: Daten pro Case kommen aus Methoden.
Enums in match
match vergleicht mit ===, und ein Enum-Case ist nur mit sich selbst identisch, also passen match und Enums zusammen. Wenn du einen Case vergisst und genau dieser Case das match erreicht, wirft PHP einen UnhandledMatchError, statt still nichts zu liefern:
Wie sich match von switch unterscheidet, steht unter match.
Enums in JSON und als Strings
json_encode() schreibt einen Backed Case als seinen Wert. Ein Pure Enum lässt sich nicht kodieren, und echo eines beliebigen Case scheitert, weil ein Enum ein Objekt ist und kein String. Gib stattdessen ->value oder ->name aus:
echo Role::Admin; wirft einen Error („Object of class Role could not be converted to string“), und Enums können __toString() nicht implementieren. Auf dem Rückweg liefert JSON einen einfachen String, also wandelst du ihn wie gezeigt mit from() oder tryFrom() um. Mehr zum Kodieren unter json_encode.
Typische Fehler mit Enums
Drei Fehler tauchen immer wieder auf. Ein Case ist nie gleich seinem Wert, ein Case kann kein Array-Schlüssel sein, und new funktioniert bei einem Enum nicht:
Wenn du eine Map mit den Cases selbst als Schlüssel brauchst, verwendest du SplObjectStorage oder WeakMap, die Objekte als Schlüssel akzeptieren.
Häufig gestellte Fragen
Wie bekomme ich in PHP den Wert eines Enums?
Bei einem Backed Enum liest du ->value: Status::Active->value ist 'active'. Jeder Case hat außerdem ->name, den Namen des Case als String ('Active'). Ein Pure Enum (ohne : string oder : int) hat nur ->name.
Was ist der Unterschied zwischen from() und tryFrom() bei PHP-Enums?
Beide machen aus einem Wert einen Case eines Backed Enums. Status::from('active') liefert den Case oder wirft einen ValueError, wenn kein Case diesen Wert hat; Status::tryFrom('nope') liefert stattdessen null. Verwende tryFrom() für Nutzereingaben und from(), wenn ein falscher Wert ein Bug ist.
Wie bekomme ich in PHP alle Werte eines Enums?
Status::cases() liefert jeden Case in der Reihenfolge der Deklaration. Für die Werte eines Backed Enums verwendest du array_column(Status::cases(), 'value'), für die Namen array_column(Status::cases(), 'name').
Was ist der Unterschied zwischen einem Pure Enum und einem Backed Enum?
Ein Pure Enum (enum Suit { case Hearts; }) hat Cases, die nur Namen sind. Ein Backed Enum (enum Suit: string { case Hearts = 'H'; }) gibt jedem Case einen eindeutigen Wert vom Typ int oder string, den du brauchst, um ihn in einer Datenbank zu speichern, in ein Formular oder JSON zu schreiben und mit from() oder tryFrom() zurückzuwandeln.
Kann ein PHP-Enum Methoden haben?
Ja. Enums können Methoden, statische Methoden und Konstanten haben und Interfaces implementieren. In einer Methode ist $this der aktuelle Case, also ist return match ($this) { self::Active => 'green', self::Banned => 'red' }; ein gängiges Muster. Eigenschaften können Enums nicht haben.