Menu
Coddy logo textTech

Перечисления (PHP 8.1)

Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy. Урок 59 из 91.

До php 8.1 представление фиксированного набора значений, например статусов или типов, означало использование констант класса или магических строк — оба подхода подвержены ошибкам. Перечисления (Enums) предоставляют правильный способ определить тип, который может содержать только определённые, заранее заданные значения.

Определите перечисление с помощью ключевого слова enum:

<?php
enum Status {
    case Pending;
    case Active;
    case Completed;
}

$status = Status::Active;
echo $status->name;

Вывод:

Active

Перечисления также могут иметь backed values — строковые или целочисленные значения, связанные с каждым case. Это полезно при хранении перечислений в базах данных или API:

<?php
enum Status: string {
    case Pending = 'pending';
    case Active = 'active';
    case Completed = 'completed';
}

$status = Status::Active;
echo $status->value;

Вывод:

active

Backed enum предоставляют метод from() для создания enum из его значения, а tryFrom() возвращает null вместо выбрасывания ошибки для недопустимых значений:

<?php
$status = Status::from('active');      // Возвращает Status::Active
$invalid = Status::tryFrom('unknown'); // Возвращает null

Перечисления также могут содержать методы, что делает их мощным инструментом для инкапсуляции связанной логики. Они без проблем работают с подсказками типов, гарантируя, что ваши функции принимают только допустимые значения — больше не нужно проверять, соответствует ли строка ожидаемым вариантам.

challenge icon

Задание

Легко

Давайте создадим систему управления заказами, которая использует перечисления для типобезопасного представления статусов заказов. Вместо строк, в которых можно допустить опечатку или указать недопустимое значение, вы создадите backed enum, сопоставляющий каждый статус со значением, удобным для базы данных.

Вы организуете код в three файлах:

  • OrderStatus.php: Create строковый backed enum под названием OrderStatus с four cases:
    • Pending backed значением 'pending'
    • Processing backed значением 'processing'
    • Shipped backed значением 'shipped'
    • Delivered backed значением 'delivered'
    Add method label(), который возвращает понятное человеку description для each статуса:
    • Pending возвращает "Awaiting confirmation"
    • Processing возвращает "Being prepared"
    • Shipped возвращает "On the way"
    • Delivered возвращает "Order complete"
  • Order.php: Create class Order, использующий enum. Подключите файл OrderStatus. Class должен:
    • Accept идентификатор заказа (строка) и OrderStatus в своём constructor, используя продвижение параметров constructor
    • Иметь method getInfo(), который возвращает "Order [id]: [status label]"
    • Иметь method getStatusValue(), который возвращает backed value статуса (полезно для хранения в базе данных)
  • main.php: Подключите файл Order. Вы получите два входных значения: идентификатор заказа и строку статуса (например, "shipped"). Используйте tryFrom(), чтобы безопасно convert строковый input в enum OrderStatus. Если статус действителен, Create Order и выведите две строки:
    • Результат getInfo()
    • Результат getStatusValue()
    Если строка статуса invalid, выведите "Invalid status".

Этот challenge демонстрирует, как enum обеспечивают type safety. Ваш class Order может принимать только действительные статусы, а method tryFrom() позволяет безопасно обрабатывать пользовательский input без риска получить invalid values.

Попробуйте сами

<?php

require_once 'Order.php';

// Прочитать ввод
$orderId = trim(fgets(STDIN));
$statusString = trim(fgets(STDIN));

// TODO: Используйте OrderStatus::tryFrom() для безопасного преобразования строки статуса в enum
// tryFrom() возвращает null, если значение недопустимо

// TODO: Если статус валиден, создайте Order и выведите:
// - Результат getInfo()
// - Результат getStatusValue()

// TODO: If the status is invalid, print "Invalid status"

?>
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор PHP