International PHP Conference Berlin 2025

Примеры

Пример #1 Базовые ограниченные значения

<?php

enum SortOrder
{
case
Asc;
case
Desc;
}

function
query($fields, $filter, SortOrder $order = SortOrder::Asc)
{
/* ... */
}

?>

Функция query() теперь безопасно продолжает работу, поскольку параметр $order гарантирует, что аргумент будет либо вариантом SortOrder::Asc, либо вариантом SortOrder::Desc. Другое значение привело бы к исключению TypeError, поэтому функция обойдётся без проверки ошибок или тестирования.

Пример #2 Расширенные эксклюзивные значения

<?php

enum UserStatus: string
{
case
Pending = 'P';
case
Active = 'A';
case
Suspended = 'S';
case
CanceledByUser = 'C';

public function
label(): string
{
return match (
$this) {
static::
Pending => 'В ожидании',
static::
Active => 'Активный',
static::
Suspended => 'Приостановленный',
static::
CanceledByUser => 'Отменено пользователем',
};
}
}

?>

В этом примере статус пользователя ограничивается единственным значением и только из следующих вариантов: UserStatus::Pending, UserStatus::Active, UserStatus::Suspended или UserStatus::CanceledByUser. Определение в сигнатуре функции параметра с типом UserStatus разрешит функции принимать только эти четыре значения, точка.

Каждому из четырёх значений доступен метод label(), который возвращает строку, удобную для чтения человеком. Эта строка не зависит от строки со скалярным эквивалентом «машинного имени», который, например, хранят в поле базы данных или выводят как значение элемента выпадающего списка в HTML-форме.

<?php

foreach (UserStatus::cases() as $case) {
printf(
"<option value=\"%s\">%s</option>\n",
$case->value,
$case->label()
);
}

?>

Добавить

Примечания пользователей 1 note

up
9
php-net at mentordosnerds dot com
1 year ago
Additional use-case examples:
<?php

trait EnumNamesTrait
{
abstract public static function
cases(): array;

public static function
names(): array
{
return
array_map(fn($enum) => $enum->name, static::cases());
}
}

trait
EnumValuesTrait
{
abstract public static function
cases(): array;

public static function
values(): array
{
return
array_map(fn($enum) => $enum->value, static::cases());
}
}

trait
EnumArraySerializableTrait
{
use
EnumNamesTrait;
use
EnumValuesTrait;

public static function array(): array
{
return
array_combine(static::names(), static::values());
}
}

trait
EnumJsonSerializableTrait
{
use
EnumArraySerializableTrait;

public static function
jsonSerialize(): string
{
return
json_encode(static::array());
}
}

enum
Suit: string
{
case
Clubs = '♣';
case
Diamonds = '♦';
case
Hearts = '♥';
case
Spades = '♠';

use
EnumJsonSerializableTrait;

public const DEFAULT =
self::Hearts;

public static function default(): static
{
return
self::DEFAULT;
}
}

var_dump(
Suit::cases(),
Suit::values(),
Suit::names(),
Suit::array(),
Suit::jsonSerialize(),
Suit::default(),
);
To Top