Od wersji PHP 8.1 typ danych Enum może być używany do definiowania dokładnych wartości wyliczeniowych dla listy. Jest to przydatne w przypadkach, gdy wiemy, że wartość zmiennej może przyjmować tylko kilka określonych wartości.
Na przykład w ten sposób przechowuję typy powiadomień:
enum OrderNotificationType: string{case Email = 'email';case Sms = 'tekst';}
W PHP typ danych Enum jest klasycznym obiektem, który zachowuje się jak specjalny typ stałej, ale posiada również instancję, którą można przekazać dalej. Jednak w przeciwieństwie do zwykłego obiektu, podlega on pewnym ograniczeniom.
Chociaż enumy są zbudowane na bazie klas i obiektów, nie obsługują wszystkich funkcji związanych z obiektami. W szczególności obiekty enum nie mogą posiadać stanu wewnętrznego (zawsze muszą być klasą statyczną).
Konkretna lista różnic:
Następujące właściwości obiektu są dostępne i zachowują się tak samo jak każdy inny obiekt:
TARGET_CLASS
zawiera same Enumy. Filtr docelowy TARGET_CLASS_CONST
obejmuje przypadki Enum.__call
, __callStatic
i __invoke
.__CLASS__
i __FUNCTION__
zachowują się jak normalne stałe::class
na typie Enum jest obliczana jako pełna nazwa typu danych, łącznie z przestrzenią nazw, dokładnie tak, jak w przypadku obiektu. Magiczna stała ::class
na instancji typu Case
jest również obliczana jako typ Enum, ponieważ jest to instancja innego typu.Wyobraźmy sobie, że mamy enum reprezentujące typy kombinezonów. W tym przypadku wystarczy zdefiniować typ Suit
i zapisać poszczególne prawidłowe wartości.
Następnie otrzymujemy instancję danej opcji klasycznie poprzez kwadraturę, tak jak w przypadku pracy ze stałą statyczną.
Przykład definiowania Enum, wywoływania go przez określony typ i przekazywania do funkcji:
enum Suit{case Hearts;case Diamonds;case Clubs;case Spades;}function doStuff(Suit $s){// ...}doStuff(Suit::Spades);
Podstawową przewagą enumów nad obiektami i stałymi jest to, że łatwo jest porównywać ich wartości.
Podstawowe porównanie, w którym pracujemy z określoną wartością, można przeprowadzić w następujący sposób:
$a = Suit::Spades;$b = Suit::Spades;$a === $b; // true
Bardzo często trzeba też zdecydować, czy dana wartość należy do poprawnego wyliczenia wartości Enum. Można to łatwo sprawdzić w następujący sposób:
$a = Suit::Spades;$a instanceof Suit; // true
Wartość określonego typu możemy odczytać albo jako nazwę stałej wywołującej, albo bezpośrednio jako zdefiniowaną wartość rzeczywistą (jeśli taka istnieje):
enum Colors{case Red;case Blue;case Green;public function getColor(): string{return $this->name;}}function paintColor(Colors $colors): void{echo "Farba:" . $colors->getColor();}
Wartość stałej wywołującej jest odczytywana przez właściwość name
. Ważne jest również to, że w typie danych Enum można bezpośrednio zaimplementować funkcję niestandardową, którą można wywoływać nad każdym Enum.
Jeśli dany Enum implementuje również wartości rzeczywiste (które są ukryte pod każdą stałą), można również odczytać ich wartość:
enum OrderNotificationType: string{case Email = 'email';case Sms = 'tekst';}$type = OrderNotificationType::Email;echo $type->value;
Często zachodzi potrzeba wypisania (np. użytkownikowi w komunikacie o błędzie) wszystkich możliwych wartości, jakie może przyjmować Enum. W przypadku używania stałych nie było to możliwe, natomiast w przypadku funkcji Enum jest to łatwe:
Suit::cases();
Zwraca [Suit::Hearts, Suit::Diamonds, Suit::Clubs, Suit::Spades]
.
Możemy łatwo sprawdzić, czy dana zmienna nieznana zawiera Enum, stosując warunek:
if ($haystack instanceof \BackedEnum) {
Każdy obiekt Enum jest automatycznie dzieckiem ogólnego interfejsu BackedEnum
.
Więcej informacji można znaleźć w dyskusji na GitHubie 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:
Články píše Jan Barášek © 2009-2024 | Kontakt | Mapa webu
Status | Aktualizováno: ... | pl