Backed enumerations
Achterliggende enumeraties
Standaard hebben Enumerated Cases geen scalair equivalent. Het zijn simpelweg singleton-objecten. Er zijn echter voldoende gevallen waarin een Enumerated Case in staat moet zijn om terug te keren naar een database of een vergelijkbare datastore, dus het is nuttig om een ingebouwd scalair (en dus triviaal serialiseerbaar) equivalent intrinsiek gedefinieerd te hebben.
Om een scalair equivalent voor een Enumeration te definiëren, is de syntaxis als volgt:
<?php
enum Suit: string
{
case Hearts = 'H';
case Diamonds = 'D';
case Clubs = 'C';
case Spades = 'S';
}
?>
Een case die een scalair equivalent heeft, wordt een Backed Case genoemd, omdat het "Achterliggend" is door een eenvoudiger waarde. Een Enum die alle Backed Cases bevat, wordt een "Backed Enum" genoemd. Een Backed Enum mag alleen Backed Cases bevatten. Een Pure Enum mag alleen Pure Cases bevatten.
Een Backed Enum kan worden ondersteund door types van int of string, en een gegeven enumeratie ondersteunt slechts één type tegelijk (dat wil zeggen, geen union van int|string). Als een enumeratie is gemarkeerd als zijnde met een scalair equivalent, moeten alle cases een unieke scalair equivalent expliciet gedefinieerd hebben. Er zijn geen automatisch gegenereerde scalair equivalents (bijv. opeenvolgende gehele getallen). Backed cases moeten uniek zijn; twee backed enum cases mogen niet hetzelfde scalair equivalent hebben. Een constante kan echter naar een case verwijzen, wat effectief een alias creëert. Zie Enumeration constants.
De equivalente waarden kunnen een constante scalair expressie zijn. Voor PHP 8.2.0 moesten de equivalente waarden literalen of literaal expressies zijn. Dit betekent dat constanten en constante expressies niet werden ondersteund. Dat wil zeggen, 1 + 1 was toegestaan, maar 1 + SOME_CONST was dat niet.
Backed Cases hebben een extra alleen-lezen eigenschap, value, die de waarde is die in de definitie is gespecificeerd.
<?php
print Suit::Clubs->value;
// Prints "C"
?>
Om de value eigenschap als alleen-lezen af te dwingen, kan een variabele niet als een referentie naar deze eigenschap worden toegewezen. Dat wil zeggen, het volgende genereert een fout:
<?php
$suit = Suit::Clubs;
$ref = &$suit->value;
// Error: Cannot acquire reference to property Suit::$value
?>
Backed enums implementeren een interne BackedEnum interface, die twee extra methoden blootlegt: from(int|string): self en tryFrom(int|string): ?self. De from() en tryFrom() methoden volgen de standaard zwakke/sterke type regels. In zwakke type modus is het accepteren van een geheel getal of string toegestaan en het systeem zal de waarde dienovereenkomstig omzetten. Het doorgeven van een float zal ook werken en worden omgezet. In strikte type modus zal het doorgeven van een geheel getal aan from() op een string-achterliggende enum (of vice versa) resulteren in een TypeError, net als een float in alle omstandigheden. Alle andere parameter types zullen in beide modi een TypeError genereren.
<?php
$record = get_stuff_from_database($id);
print $record['suit'];
$suit = Suit::from($record['suit']);
// Ongeldige gegevens genereren een ValueError: "X" is geen geldige scalair waarde voor enum "Suit"
print $suit->value;
$suit = Suit::tryFrom('A') ?? Suit::Spades;
// Ongeldige gegevens retourneren null, dus wordt Suit::Spades in plaats daarvan gebruikt.
print $suit->value;
?>
Het handmatig definiëren van een from() of tryFrom() methode op een Backed Enum resulteert in een fatale fout.