Wertgebundene Aufzählungen (Backed Enums)

Standardmäßig haben Enum-Fälle keine skalare Entsprechung. Es handelt sich einfach um Singleton-Objekte. In vielen Fällen ist es jedoch auch notwendig, einen Enum-Fall von einer Datenbank oder einem ähnlichen Datenspeicher zu lesen und in diese zu schreiben, sodass es sinnvoll ist, ein intern definiertes skalares (und damit einfach serialisierbares) Äquivalent zu haben.

Um für eine Aufzählung eine skalare Entsprechung zu definieren, wird folgende Syntax verwendet:

<?php

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

Ein Fall, der eine skalare Entsprechung hat, wird als "Backed Case" bezeichnet, da er durch einen einfacheren Wert "unterstützt" wird. Eine Enum, die ausschließlich Backed Cases enthält, wird als "Backed Enum" bezeichnet. Eine Backed Enum kann nur Backed Cases enthalten. Eine Pure Enum kann nur Pure Cases enthalten.

Eine Backed Enum kann entweder durch den Typ int oder den Typ string unterstützt werden, wobei eine gegebene Aufzählung jeweils nur einen einzigen Typ unterstützt (d. h. der Vereinigungstyp int|string wird nicht unterstützt). Wenn eine Aufzählung als "skalar äquivalent" gekennzeichnet ist, müssen alle Fälle eine eindeutige, explizit definierte skalare Entsprechung haben. Es gibt keine automatisch generierten skalare Entsprechungen (z. B. fortlaufende Ganzzahlen). Backed Cases müssen eindeutig sein; zwei Backed Enum Cases dürfen nicht dieselbe skalare Entsprechung haben. Eine Konstante kann jedoch auf einen Fall verweisen und somit einen Alias erzeugen. Siehe Aufzählungskonstanten.

Die Entsprechungen müssen Literale sein oder literale Ausdrücke. Konstanten und Ausdrücke mit Konstanten werden nicht unterstützt. Das heißt, 1 + 1 ist erlaubt, aber 1 + SOME_CONST ist nicht erlaubt.

Backed Cases haben eine zusätzliche schreibgeschützte Eigenschaft, value, die der in der Definition angegebene Wert ist.

<?php

print Suit::Clubs->value;
// Gibt "C" aus
?>

Um sicherzustellen, dass die Eigenschaft value schreibgeschützt ist, kann eine Variable nicht als Referenz zugewiesen werden. Das bedeutet, dass Folgendes einen Fehler auslöst:

<?php

$suit
= Suit::Clubs;
$ref = &$suit->value;
// Error: Cannot acquire reference to property Suit::$value
?>

Backed Enums implementieren die interne Schnittstelle BackedEnum, die zwei zusätzliche Methoden zur Verfügung stellt:

  • from(int|string): self akzeptiert einen skalaren Wert und gibt den entsprechenden Enum-Fall zurück. Wird ein solcher nicht gefunden, löst das einen ValueError aus. Dies ist vor allem in Fällen nützlich, in denen der eingegebene Wert vertrauenswürdig ist und ein fehlender Enum-Wert als Fehler angesehen werden sollte, der die Anwendung abbricht.
  • tryFrom(int|string): ?self akzeptiert einen skalaren Wert und gibt den entsprechenden Enum-Fall zurück. Wenn keiner gefunden wird, wird null zurückgegeben. Dies ist vor allem in Fällen nützlich, in denen der eingegebene Wert nicht vertrauenswürdig ist und der Aufrufer seine eigene Fehlerbehandlung oder Logik für Standardwerte implementieren möchte.

Die Methoden from() und tryFrom() folgen den Standardregeln für schwache bzw. starke Typisierung. Bei schwacher Typisierung ist die Übergabe einer Ganzzahl oder einer Zeichenkette zulässig und das System wandelt den Wert entsprechend um. Auch Gleitkommazahlen können übergeben werden und werden dann entsprechend umgewandelt. Im Modus der strengen Typisierung führt die Übergabe einer Ganzzahl an from() bei einer Enum mit Zeichenketten (oder umgekehrt) zu einem TypeError. Für Gleitkommazahlen gelten in allen Fällen die gleichen Typisierungsregeln. Bei allen anderen Typen wird in beiden Modi ein TypeError ausgelöst.

<?php

$record
= get_stuff_from_database($id);
print
$record['suit'];

$suit = Suit::from($record['suit']);
// Ungültige Daten führen zu einem ValueError:
// "X" is not a valid scalar value for enum "Suit"
print $suit->value;

$suit = Suit::tryFrom('A') ?? Suit::Spades;
// Ungültige Daten ergeben null, also wird stattdessen Suit::Spades verwendet.
print $suit->value;
?>

Die manuelle Definition der Methoden cases() oder tryFrom() führt bei einer Enum zu einem fatalen Fehler.

add a note

User Contributed Notes

There are no user contributed notes for this page.
To Top