dinist

PHP - Enum 사용하기 본문

Web/PHP

PHP - Enum 사용하기

dinist 2023. 5. 24. 15:58

PHP 8.1 버전부터 Enum이라는 열거체를 사용할 수 있게 되었습니다.

Enum이 도입되기 이전에는 Class를 활용하여 Enum과 비슷한 느낌으로 구현하여 사용했었는데요

 

PHP버전이 8.2까지 나왔으니 이제 Enum을 사용해 봅시다.

 

 

- Basic Enumerations

기본적인 열거형의 모습은 다음과 같습니다.

enum Fruit
{
    case Apple;
    case Banana;
    case Coconut;
    case COconut;
}

 

위 Fruit 열거형에는 3가지의 값이 선언되어 있습니다.

이 열거형의 값은 직접 사용해도 되고, 변수에도 할당할 수 있습니다.

typePrinter 라는 함수에는 Fruit 열거형만 인자 값으로 넘길 수 있도록 타입힌팅 하였습니다.

function typePrinter(Fruit $fruit)
{
    return gettype($fruit);
}

$banana = Fruit::Banana;

var_dump($banana);		// enum(Fruit::Banana)
var_dump(Fruit::Banana);	// enum(Fruit::Banana)
var_dump("Banana");		// string(6) "Banana"


echo typePrinter($banana)."\n";		// object
echo typePrinter(Fruit::Banana)."\n";	// object
echo typePrinter("Banana");		// Uncaught TypeError: typePrinter(): Argument #1 ($fruit) must be of type Fruit, string given

위와 같은 열거체는 basic enum이며 각 enum 내에 있는 case들은 값을 지정하지 않았기 때문에

Pure Case. 즉, 순수 케이스라고 불리며, 각 케이스는 대소문자를 구분합니다.

각각의 케이스들은 해당 열거체의 인스턴스로 구현되어 있어 내부적으로 클래스처럼 표현됩니다.

그리고 각각의 케이스는 읽기전용 속성인 name을 가지고 있습니다. 

enum Fruit{
    case Apple;
    case Banana;
    case Coconut;
    case CoconuT;
}


$coconut = Fruit::Coconut;

var_dump(Fruit::Coconut == Fruit::Coconut);	// bool(true)
var_dump(Fruit::Coconut == $coconut);	// bool(true)
var_dump(Fruit::CoconuT == $coconut);	// bool(false)
var_dump(Fruit::Coconut == Fruit::CoconuT);	// bool(false)

var_dump(Fruit::Apple->name);	// string(5) "Apple"
var_dump(Fruit::Banana->name);	// string(6) "Banana"
var_dump(Fruit::Coconut->name);	// string(7) "Coconut"
var_dump(Fruit::CoconuT->name); // string(7) "CoconuT"

 

- Backed Enumerations

위에서 설명했던 Basic Enumeration과는 달리 데이터를 저장하는등의 작업이 필요한 경우 사용하는 열거체입니다.

즉 열거형에 기본값을 지정할 수 있으며 지정할 수 있는 기본값의 타입은 int,string 두가지 중 한가지만

사용할 수 있습니다. 반드시 한가지 타입만 통일하여 사용해야합니다.

(int와 string을 동시에 사용할 수 없습니다.)

구조는 아래와 같습니다.

// int 로만 사용하거나
enum Fruit : int{
    case Apple = 500;
    case Banana = 600;
    case Coconut = 700;
    case CoconuT = 800;
}

// string 으로만 사용하거나
enum Fruit : string{
    case Apple = "A";
    case Banana = "B";
    case Coconut = "C";
    case CoconuT = "D";
}


// 아래와 같이 사용 불가!
enum Fruit : string | int {
    case Apple = 500;
    case Banana = "B";
    case Coconut = 700;
    case CoconuT = "D";
}

 

또한 지정하는 값은 리터럴(literal) 값이어야 합니다. 상수 및 상수 표현식을 사용할 수 없습니다.

아까 basic enum에서 name 읽기전용 프로퍼티가 있었던것 처럼 backed enum에서는 value 읽기전용 프로퍼티가 있습니다.

enum Fruit : int{
    case Apple = 500;
    case Banana = 600;
    case Coconut = 700;
    case CoconuT = 800;
}

var_dump(Fruit::Apple->value);	// int(500)

Backed Enum은 내부적으로 BackedEnum 인터페이스를 구현하고 있어 두가지 메소드를 사용할 수 있습니다.

 

- from(int|string)  : 스칼라 값을 통해 해당 Enum Case를 반환합니다. 만약 찾지 못하면 ValueError Exception이 발생합니다. 예외를 리턴하기때문에 값을 찾지못했을때 예외를 발생시켜야할경우 사용하면 유용합니다.

 

- tryFrom(int|string) : 스칼라 값을 통해 해당 Enum Case를 반환합니다 만약 찾지 못하면 null을 반환합니다.

 

Backed Enum에서 from, tryFrom 메소드를 직접 정의하면 치명적인 오류가 발생한다고 합니다. (php 공식문서에 나옴)

 

 

출처 (많은도움이 되었습니다.)

 

https://www.php.net/manual/en/language.enumerations.php

https://edykim.com/ko/post/enumerations-in-php/

https://hyeon.pro/dev/php-8-1-enums/