상현에 하루하루
All 개발자의 하루

PHP 8.1: Enums

( 업데이트: )

PHP8.1에는 Enums가 추가됩니다.

enum Status
{
  case DRAFT;
  case PUBLISHED;
  case ARCHIVED;
}

열거형의 이점은 상수 값의 컬렉션을 나타내지만 가장 중요한 것은 이러한 값을 다음과 같이 입력할 수 있다는 것입니다.

class BlogPost
{
  public function __construct(
    public Status $status,
  ) {}
}

이 예에서 열거형을 만들고 전달하면 BlogPost는 다음과 같습니다.

$post = new BlogPost(Status::DRAFT);

열거형에 대해 자세히 살펴보겠습니다!

Enum methods

열거형은 클래스와 마찬가지로 메서드를 정의할 수 있습니다. 이것은 특히 match 연산자와 함께 사용할 때 매우 강력한 기능입니다.

enum Status
{
    case DRAFT;
    case PUBLISHED;
    case ARCHIVED;

    public function color(): string
    {
        return match($this)
        {
            Status::DRAFT => 'grey',
            Status::PUBLISHED => 'green',
            Status::ARCHIVED => 'red',
        };
    }
}

방법은 다음과 같이 사용할 수 있습니다.

$status = Status::ARCHIVED;
$status->color();    // 'red'

정적 메서드도 허용됩니다.

enum Status
{
    // ...
    public static function make(): Status
    {
        // ...
    }
}

그리고 self 열거형 내에서 다음을 사용할 수도 있습니다.

enum Status
{
  // ...
    public function color(): string
    {
        return match($this)
        {
            self::DRAFT => 'grey',
            self::PBULISHED => 'green',
            self::ARCHIVED => 'red',
        };
    }
}

Enum interfaces

열거형은 일반 클래스와 마찬가지로 인터페이스를 구현할 수 있습니다.

interface HasColor
{
    public function color(): string;
}
enum Status implements HasColor
{
    case DRAFT;
    case PUBLISHED;
    case ARCHIVED;
    
    public function color(): string { /* … */ }
}

Enum values – aka “Backed enums”

열거형 값은 내부적으로 객체로 표시되지만 원하는 경우 객체에 값을 할당할 수 있습니다. 이 것은 예를 들어 데이터베이스 직렬화입니다.

enum Status: string
{
  case DRAFT = 'draft';
  case PUBLISHED = 'published';
  case ARCHIVED = 'archived';
}

열거형 정의의 유형 선언에 유의하십시오. 모든 열거형 값이 지정된 유형임을 나타냅니다. intstring만 열거형 값으로 허용됩니다.

enum Status: string
{
  case DRAFT = 1;
  case PUBLISHED = 2;
  case ARCHIVED = 3;
}

형식화된 열거형에 대한 기술 용어는 더 간단한 값으로 지원 되기 떄문에 “backed enums”이라고 합니다. 열거형 값을 할당하기로 결정했다면 모든 케이스에 값이 있어야 합니다. 당신은 그들을 혼합하고 일치시킬 수 없습니다. “backed”되지 않은 열거형을 “pure enums”라고 합니다.

  • 값을 할당할 것이라면 모든 케이스에 값을 할당 해야한다.
  • 혼합하고 일치 할 수 없다

Backed enums with interface

backed enums와 인터페이스를 결합하는 경우 implements 키워드가 필요합니다.

enum Status: string implements HasColor // HasColor interface
{
  case DRAFT = 'draft';
  case PUBLISHED = 'published';
  case ARCHIVED = 'archived';

  // ...
}

Serializing backed enums

열거형 케이스에 값을 할당하는 경우 해당 케이스를 직렬화 및 역직렬화 하는 방법이 필요할 수 있습니다. 직렬화한다는 것은 열거형 값에 접근할 방법이 필요하다는 것을 의미합니다. 읽기 전용 공용 속성

$value = Status::PUBLISHED->value;;  // 2

다음을 사용하여 값에서 열거형을 복원할 수 있습니다. Enum::form

$status = Status::form(2);  // Status::PUBLISHED

알 수 없는 값이 전달되면 tryFrom반환되어 null을 반환합니다. 당신이 사용한다면 from 예외가있을 것입니다.

$status = Status::from('unknown');  // ValueError
$status = Status::tryFrom('unknown');  // null

열거형에서 내장 serializeunserialize함수를 사용할 수도 있습니다. 또한 json_encode 지원되는 열거형과 함께 사용할 수 있으며 그 결과는 열거형 값이 됩니다. 이 동작은 JsonSerializable을 통해 재정의할 수 있습니다.

Listing enum values

정적 메서드를 사용하여 열거형 내에서 사용가능한 모든 사례 목록을 가져올 수 있습니다. Enum::cases()

Status::cases();

/* [
  Status::DRAFT,
  Status::PUBLISHED,
  Status::ARCHIVED,
] */

이 배열에는 실제 열거형 객체가 포함되어 있습니다.

array_map(
  fn(Status $status) => $status->color(),
  Status::cases()
);

Enums as array keys

열거형 값은 실제로 객체이기 때문에 현재 배열 키로 사용할 수 없습니다. 다음은 오류가 발생합니다.

$list = [
  Status::DRAFT => 'draft', //error!
  // ...
];

즉, SplObjectStorageWeakMaps에서 열거형은 키로만 사용할 수 있습니다.

Traits

열거형은 클래스처럼 특성을 사용할 수 있지만 몇 가지 제한 사항이 더 있습니다. 내장 enum 메소드를 재정의할 수 없으며 클래스 속성을 포함할 수 없습니다. 이런한 속성은 enum에서 금지됩니다.

Reflection and attributes

예상대로 열거형을 처리하기 위해 몇 가지 리플렉션 클래스가 추가되었습니다.

  • ReflectionEnum
  • ReflectionEnumUnitCase
  • ReflectionEnumBackedCase
  • ✨new enum_exists

일반 클래스 및 속성과 마찬가지로 열거형과 해당 사례는 속성을 사용하여 주석을 달 수 있습니다.

참고 TARGET_CLASS 또한 열거형 필터를 포함


PHP 8.1: Enums – stitcher.io 글을 번역하였습니다.