Od PHP 8.1 lze použít datový typ Enum, který slouží pro definici přesných výčtových hodnot seznamu. Hodí se to pro případy, kdy víme, že hodnota proměnné může nabývat jen konkrétních několika hodnot.
Například takto ukládám typy notifikací:
enum OrderNotificationType: string{case Email = 'email';case Sms = 'sms';}
Datový typ Enum je v PHP klasický objekt, který se chová jako speciální typ konstanty, ale navíc má instanci, kterou můžeme předávat dál. Na rozdíl od běžného objektu se na něj ale vztahuje řada omezení.
Přestože jsou enumy postaveny na třídách a objektech, nepodporují všechny funkce související s objekty. Zejména je zakázáno, aby objekty enumů měly vnitřní stav (vždy musí jít o statickou třídu).
Konkrétní výčet rozdílů:
Následující funkce objektu jsou k dispozici a chovají se stejně jako u jakéhokoli jiného objektu:
TARGET_CLASS
zahrnuje samotné Enumy. Cílový filtr TARGET_CLASS_CONST
zahrnuje případy Enum.__call
, __callStatic
a __invoke
.__CLASS__
a __FUNCTION__
se chovají jako normální konstanty::class
na typu Enum se vyhodnocuje jako celý název datového typu včetně případného jmenného prostoru, přesně stejně jako u objektu. Magická konstanta ::class
na instanci typu Case
se také vyhodnocuje jako typ Enum, protože se jedná o instanci jiného typu.Představte si, že máme enum reprezentující druhy obleků. V takovém případě stačí definovat typ Suit
a uložit jednotlivé validní hodnoty.
Instanci konkrétní možnosti pak získáme klasicky přes čtyřtečku, jako při práci se statickou konstantou.
Ukázka definici Enumu, jeho vyvolání podle konkrétního typu a předání do funkce:
enum Suit{case Hearts;case Diamonds;case Clubs;case Spades;}function doStuff(Suit $s){// ...}doStuff(Suit::Spades);
Zásadní výhoda enumu oproti objektům a konstantám je ta, že lze snadno porovnávat jejich hodnotu.
Základní porovnání, že pracujeme s konkrétní hodnotou můžeme udělat takto:
$a = Suit::Spades;$b = Suit::Spades;$a === $b; // true
Velmi často také potřebujeme rozhodnout, že konkrétní hodnota patří do validního výčtu hodnot Enumu. To lze ověřit snadno takto:
$a = Suit::Spades;$a instanceof Suit; // true
Konkrétní hodnotu typu můžeme přečíst buď jako název volací konstanty, nebo přímo reálnou definovanu hodnotu (pokud existuje):
enum Colors{case Red;case Blue;case Green;public function getColor(): string{return $this->name;}}function paintColor(Colors $colors): void{echo "Paint: " . $colors->getColor();}
Hodnota volací konstanty se čte přes property name
. Důležité je také to, že přímo do datového typu Enum lze implementovat vlastní funkci, kterou můžeme nad každým Enumem zavolat.
Pokud konkrétní Enum implementuje také reálné hodnoty (které se skrývají pod každou konstantou), lze přečíst i jejich hodnotu:
enum OrderNotificationType: string{case Email = 'email';case Sms = 'sms';}$type = OrderNotificationType::Email;echo $type->value;
Často potřebujeme (například uživateli v chybové hlášce) vypsat všechny možné hodnoty, kterých může Enum nabývat. Při použítí konstant toto možné nebylo, Enum to umožňuje snadno:
Suit::cases();
Vrátí: [Suit::Hearts, Suit::Diamonds, Suit::Clubs, Suit::Spades]
.
Že konkrétní neznámá proměnná obsahuje Enum můžeme snadno ověřit podmínkou:
if ($haystack instanceof \BackedEnum) {
Každý Enum objekt je automaticky potomek obecného rozhraní \BackedEnum
.
Další informace jsou v diskusi na GitHubu PhpStan: https://github.com/phpstan/phpstan/issues/7304
Jan Barášek Více o autorovi
Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.
Rád vám pomůžu:
Nabízím trénink vývojářů, konzultace, školení a analýzu návrhových vzorů. Osobně v Praze nebo online.
Napište mi, pokud si nevíte rady.
Lektor: Jan Barášek
Články píše Jan Barášek © 2009-2024 | Kontakt | Mapa webu
Status | Aktualizováno: ... | cs