Починаючи з версії PHP 8.1, тип даних Enum можна використовувати для визначення точних значень перерахування для списку. Це корисно у випадках, коли ми знаємо, що значення змінної може приймати лише декілька конкретних значень.
Наприклад, так я зберігаю типи повідомлень:
enum OrderNotificationType: string{case Email = 'електронна пошта';case Sms = 'текст';}
У мові PHP тип даних Enum є класичним об'єктом, який поводиться як спеціальний тип константи, але також має екземпляр, який можна передавати. Однак, на відміну від звичайного об'єкта, на нього поширюється низка обмежень.
Хоча зчислення побудовані поверх класів та об'єктів, вони не підтримують всю функціональність, пов'язану з об'єктами. Зокрема, перечислювальним об'єктам заборонено мати внутрішній стан (вони завжди повинні бути статичним класом).
Конкретний перелік відмінностей:
Наступні функції об'єкта доступні і поводяться так само, як і будь-який інший об'єкт:
TARGET_CLASS
включає в себе самі переліки. Цільовий фільтр TARGET_CLASS_CONST
включає в себе випадки Enum.__call
, __callStatic
та __invoke
.__КЛАС__
та __ФУНКЦІЯ__
поводять себе як звичайні константи::class
на типі Enum оцінюється як повне ім'я типу даних, включаючи будь-який простір імен, точно як для об'єкту. Магічна константа ::class
на екземплярі типу Case
також обчислюється як тип Enum, оскільки він є екземпляром іншого типу.Уявіть собі, що у нас є перерахування, яке представляє типи позовів. У цьому випадку нам потрібно лише визначити тип Suit
і зберігати окремі допустимі значення.
Потім ми отримуємо екземпляр конкретної опції класично через квадратик, як при роботі зі статичною константою.
Приклад опису зчислення Enum, виклику його за конкретним типом та передачі у функцію:
enum Suit{case Hearts;case Diamonds;case Clubs;case Spades;}function doStuff(Suit $s){// ...}doStuff(Suit::Spades);
Принципова перевага перечислень над об'єктами та константами полягає в тому, що легко порівнювати їх значення.
Базове порівняння, що ми працюємо з конкретною величиною, можна зробити наступним чином:
$a = Suit::Spades;$b = Suit::Spades;$a === $b; // true
Дуже часто нам також потрібно вирішити, що певне значення належить до допустимого перерахування значень Enum. Це можна легко перевірити наступним чином:
$a = Suit::Spades;$a instanceof Suit; // true
Ми можемо прочитати значення конкретного типу або як ім'я викликаючої константи, або безпосередньо як реальне визначене значення (якщо воно існує):
enum Colors{case Red;case Blue;case Green;public function getColor(): string{return $this->name;}}function paintColor(Colors $colors): void{echo "Фарба:" . $colors->getColor();}
Значення викликаючої константи зчитується через властивість name
. Важливо також, що безпосередньо в типі даних Enum може бути реалізована користувацька функція, яку можна викликати над кожним Enum.
Якщо конкретний Enum реалізує також і дійсні значення (які приховані під кожною константою), то їх значення також можна прочитати:
enum OrderNotificationType: string{case Email = 'електронна пошта';case Sms = 'текст';}$type = OrderNotificationType::Email;echo $type->value;
Часто нам потрібно перерахувати (наприклад, користувачеві в повідомленні про помилку) всі можливі значення, які може приймати Enum. При використанні констант це було неможливо, Enum дозволяє це легко зробити:
Suit::cases();
Повертає [масть::Черва, масть::Бубна, масть::Трефа, масть::Піка]
.
Ми можемо легко перевірити, що певна невідома змінна містить перерахування за умовою:
if ($haystack instanceof \BackedEnum) {
Кожен об'єкт Enum автоматично є нащадком узагальненого інтерфейсу \BackedEnum
.
Більш детальну інформацію можна знайти в обговоренні на GitHub 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: ... | uk