Menu
Coddy logo textTech

Enums (PHP 8.1)

Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 91개 중 59번째.

PHP 8.1 이전에는 상태나 유형과 같은 고정된 값 집합을 표현하기 위해 클래스 상수나 매직 문자열을 사용해야 했으며, 이는 두 가지 모두 오류가 발생하기 쉬운 방식이었습니다. Enums(열거형)는 특정하고 미리 정의된 값만 가질 수 있는 타입을 정의하는 적절한 방법을 제공합니다.

enum 키워드를 사용하여 열거형(enum)을 정의합니다:

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

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

출력:

Active

열거형(Enums)은 각 케이스와 연관된 문자열 또는 정수 값인 백드 값(backed values)을 가질 수도 있습니다. 이는 데이터베이스나 API에 열거형을 저장할 때 유용합니다:

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

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

출력:

active

Backed enums는 값으로부터 열거형을 생성하기 위한 from() 메서드와, 유효하지 않은 값에 대해 에러를 던지는 대신 null을 반환하는 tryFrom() 메서드를 제공합니다:

<?php
$status = Status::from('active');      // Status::Active를 반환합니다
$invalid = Status::tryFrom('unknown'); // null을 반환합니다

Enums는 메서드를 포함할 수도 있어, 관련 로직을 캡슐화하는 데 강력한 도구가 됩니다. 또한 타입 힌트와 원활하게 작동하여 함수가 유효한 값만 수락하도록 보장하므로, 더 이상 문자열이 예상된 옵션과 일치하는지 확인할 필요가 없습니다.

challenge icon

챌린지

쉬움

주문 상태를 타입 안전(type-safe)한 방식으로 표현하기 위해 열거형(enum)을 사용하는 주문 관리 시스템을 구축해 보겠습니다. 철자가 틀리거나 유효하지 않을 수 있는 문자열에 의존하는 대신, 각 상태를 데이터베이스 친화적인 값으로 매핑하는 backed enum을 생성합니다.

코드는 세 개의 파일로 구성됩니다:

  • OrderStatus.php — 다음과 같은 네 가지 케이스를 가진 OrderStatus라는 이름의 문자열 기반(string-backed) enum을 생성합니다:
    • Pending: 'pending' 값을 가짐
    • Processing: 'processing' 값을 가짐
    • Shipped: 'shipped' 값을 가짐
    • Delivered: 'delivered' 값을 가짐
    각 상태에 대해 사람이 읽을 수 있는 설명을 반환하는 label() 메서드를 추가합니다:
    • Pending은 "Awaiting confirmation"을 반환합니다.
    • Processing은 "Being prepared"를 반환합니다.
    • Shipped는 "On the way"를 반환합니다.
    • Delivered는 "Order complete"를 반환합니다.
  • Order.php — 해당 enum을 사용하는 Order 클래스를 생성합니다. OrderStatus 파일을 포함(include)해야 합니다. 클래스는 다음을 수행해야 합니다:
    • 생성자 프로모션(constructor promotion)을 사용하여 생성자에서 주문 ID(문자열)와 OrderStatus를 받습니다.
    • "Order [id]: [status label]" 형식을 반환하는 getInfo() 메서드를 가집니다.
    • 상태의 backed value를 반환하는 getStatusValue() 메서드를 가집니다 (데이터베이스 저장 시 유용함).
  • main.php — Order 파일을 포함합니다. 주문 ID와 상태 문자열(예: "shipped") 두 가지 입력을 받습니다. tryFrom()을 사용하여 문자열 입력을 OrderStatus enum으로 안전하게 변환합니다. 상태가 유효하면 Order 객체를 생성하고 다음 두 줄을 출력합니다:
    • getInfo()의 결과
    • getStatusValue()의 결과
    상태 문자열이 유효하지 않으면 "Invalid status"를 출력합니다.

이 챌린지는 enum이 어떻게 타입 안전성을 제공하는지 보여줍니다. Order 클래스는 유효한 상태만 받아들일 수 있으며, tryFrom() 메서드를 통해 유효하지 않은 값의 위험 없이 사용자 입력을 안전하게 처리할 수 있습니다.

치트 시트

Enum은 고정된 값 집합을 정의하는 타입 안전(type-safe)한 방법을 제공합니다. enum 키워드를 사용하여 enum을 정의합니다:

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

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

Backed enum은 각 케이스에 문자열 또는 정수 값을 연결합니다:

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

$status = Status::Active;
echo $status->value; // Outputs: active

값으로부터 enum을 생성하려면 from()을 사용하고, 유효하지 않은 값에 대해 null을 반환하려면 tryFrom()을 사용합니다:

<?php
$status = Status::from('active');      // Returns Status::Active
$invalid = Status::tryFrom('unknown'); // Returns null

Enum은 관련 로직을 캡슐화하기 위해 메서드를 포함할 수 있습니다:

<?php
enum Status: string {
    case Pending = 'pending';
    case Active = 'active';
    
    public function label(): string {
        return match($this) {
            self::Pending => 'Awaiting',
            self::Active => 'In Progress',
        };
    }
}

직접 해보기

<?php

require_once 'Order.php';

// 입력 읽기
$orderId = trim(fgets(STDIN));
$statusString = trim(fgets(STDIN));

// TODO: OrderStatus::tryFrom()을 사용하여 상태 문자열을 안전하게 열거형(enum)으로 변환하세요.
// tryFrom()은 값이 유효하지 않은 경우 null을 반환합니다.

// TODO: 상태가 유효한 경우, Order를 생성하고 다음을 출력하세요:
// - getInfo()의 결과
// - getStatusValue()의 결과

// TODO: 상태가 유효하지 않은 경우, "Invalid status"를 출력하세요.

?>
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨