dinist

PHP - Enum 사용하기 2 본문

Web/PHP

PHP - Enum 사용하기 2

dinist 2023. 5. 24. 17:03

PHP - Enum 사용하기에 이어서 작성하는 2편입니다.

 

1편!

https://dinist.tistory.com/44

 

PHP - Enum 사용하기

PHP 8.1 버전부터 Enum이라는 열거체를 사용할 수 있게 되었습니다. Enum이 도입되기 이전에는 Class를 활용하여 Enum과 비슷한 느낌으로 구현하여 사용했었는데요 PHP버전이 8.2까지 나왔으니 이제 Enum

dinist.tistory.com

 

- 메소드

Enum에서도 메소드를 구현할 수 있습니다.

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

    public function getMsg(){
        return match ($this){
            Fruit::Apple => "Apple's Color is red",
            Fruit::Banana => "Banana's Color is yellow",
            Fruit::Coconut => "Coconut's Color is unknown",
            Fruit::CoconuT => "CoconuT's Color is unknown!"
        };
    }
}

var_dump(Fruit::Apple->getMsg()); // string(20) "Apple's Color is red"

 

- 인터페이스

인터페이스를 활용할 수도 있습니다.

각 케이스별로 인스턴스가 존재하므로 $this로 접근할 수 있습니다.

interface Advertisement{
    public function getMsg() : string;
    public function getDiscountPrice() : int;
}

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

    public function getMsg(): string{
        return match ($this){
            Fruit::Apple => "Apple's Color is red",
            Fruit::Banana => "Banana's Color is yellow",
            Fruit::Coconut => "Coconut's Color is unknown",
            Fruit::CoconuT => "CoconuT's Color is unknown!"
        };
    }

    
    public function getDiscountPrice() : int
    {
        $discount_rate = 0.6;
        $price = $this->value;
        return $price * (1 - $discount_rate);
    }
}

var_dump(Fruit::Apple->getMsg());	// string(20) "Apple's Color is red"
var_dump(Fruit::Apple->getDiscountPrice());	// int(200)

 

- 정적 메소드와 cases()

정적 메소드도 사용할 수 있습니다.

Fruit enum의 case중 랜덤으로 하나를 리턴하는 함수를 만들어봅시다.

여기서 cases()라는 static 메소드를 사용하는데 이는 열거형이 UnitEnum 인터페이스를 구현하고 있어서

cases 라는 메소드를 사용할 수 있게 됩니다. 이 메소드는 열거형 내부에 선언된 모든 case를 담은 배열을 리턴합니다.

interface Advertisement{
    public function getMsg() : string;
    public function getDiscountPrice() : int;
}

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

    public function getMsg(): string{
        return match ($this){
            Fruit::Apple => "Apple's Color is red",
            Fruit::Banana => "Banana's Color is yellow",
            Fruit::Coconut => "Coconut's Color is unknown",
            Fruit::CoconuT => "CoconuT's Color is unknown!"
        };
    }
    
    public function getDiscountPrice() : int
    {
        $discount_rate = 0.6;
        $price = $this->value;
        return $price * (1 - $discount_rate);
    }

    public static function getRandomFruit() : static
    {
        $cases = static::cases();
        return $cases[array_rand($cases)];
    }
}

var_dump(Fruit::getRandomFruit()->getMsg()); // Fruit case중 무작위 msg 출력

 

- 상수사용

enum에 상수도 사용할 수 있습니다.

interface Advertisement{
    public function getMsg() : string;
    public function getDiscountPrice() : int;
}

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

    const DELICIOUS = self::Coconut;

    const BASE_MENT = "'s Color is ";

    public function getMsg(): string{
        return match ($this){
            Fruit::Apple => "Apple".self::BASE_MENT."red",
            Fruit::Banana => "Banana".self::BASE_MENT."yellow",
            Fruit::Coconut => "Coconut".self::BASE_MENT."unknown",
            Fruit::CoconuT => "CoconuT".self::BASE_MENT."unknown!"
        };
    }

    
    public function getDiscountPrice() : int
    {
        $discount_rate = 0.6;
        $price = $this->value;
        return $price * (1 - $discount_rate);
    }

    public static function getRandomFruit() : static
    {
        $cases = static::cases();
        return $cases[array_rand($cases)];
    }
}

var_dump(Fruit::Apple->getMsg());	// string(20) "Apple's Color is red"
var_dump(Fruit::Coconut === Fruit::DELICIOUS);	// bool(true)

 

- Trait

이외에 trait 도 사용할 수 있습니다.

interface Advertisement{
    public function getMsg() : string;
    public function getDiscountPrice() : int;
}

trait Boom{
    public function boom(){
        return "boom!";
    }
}

enum Fruit : int implements Advertisement{

    use Boom;

    case Apple = 500;
    case Banana = 600;
    case Coconut = 700;
    case CoconuT = 800;

    const DELICIOUS = self::Coconut;

    const BASE_MENT = "'s Color is ";

    public function getMsg(): string{
        return match ($this){
            Fruit::Apple => "Apple".self::BASE_MENT."red",
            Fruit::Banana => "Banana".self::BASE_MENT."yellow",
            Fruit::Coconut => "Coconut".self::BASE_MENT."unknown",
            Fruit::CoconuT => "CoconuT".self::BASE_MENT."unknown!"
        };
    }

    
    public function getDiscountPrice() : int
    {
        $discount_rate = 0.6;
        $price = $this->value;
        return $price * (1 - $discount_rate);
    }

    public static function getRandomFruit() : static
    {
        $cases = static::cases();
        return $cases[array_rand($cases)];
    }
}

var_dump(Fruit::getRandomFruit()->boom());

 

이외의 특징

- 생성자와 소멸자를 사용할 수 없음

- 상속 불가능

- static 또는 개체 프로퍼티 사용 불가

- 복제(clone) 불가능 -> 케이스가 싱글톤이므로 복제 미지원

- 열거형은 사용이전에 선언되어야함

 

- 직렬화 Serial

열거형은 객체와는 다르게 직렬화됩니다. serialize 이후 E 라고 표기가 되어 Enum임을 알 수 있습니다.

역직렬화 후에는 싱글톤 값을 사용할 수 있습니다.

interface Advertisement{
    public function getMsg() : string;
    public function getDiscountPrice() : int;
}

trait Boom{
    public function boom(){
        return "boom!";
    }
}

enum Fruit : int implements Advertisement{

    use Boom;

    case Apple = 500;
    case Banana = 600;
    case Coconut = 700;
    case CoconuT = 800;

    const DELICIOUS = self::Coconut;

    const BASE_MENT = "'s Color is ";

    public function getMsg(): string{
        return match ($this){
            Fruit::Apple => "Apple".self::BASE_MENT."red",
            Fruit::Banana => "Banana".self::BASE_MENT."yellow",
            Fruit::Coconut => "Coconut".self::BASE_MENT."unknown",
            Fruit::CoconuT => "CoconuT".self::BASE_MENT."unknown!"
        };
    }

    
    public function getDiscountPrice() : int
    {
        $discount_rate = 0.6;
        $price = $this->value;
        return $price * (1 - $discount_rate);
    }

    public static function getRandomFruit() : static
    {
        $cases = static::cases();
        return $cases[array_rand($cases)];
    }
}

var_dump(serialize(Fruit::Apple));		// string(19) "E:11:"Fruit:Apple";"
var_dump(Fruit::Apple === unserialize(serialize(Fruit::Apple)));		// bool(true)

 

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

https://php.watch/versions/8.1/enums

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/

'Web > PHP' 카테고리의 다른 글

PHP 폴더 복사 함수 코드  (0) 2023.07.24
[Laravel] - Eloquent에서 Enum 활용  (0) 2023.05.24
PHP - Enum 사용하기  (0) 2023.05.24
[PhpStorm] 라라벨 serve , npm dev 설정 추가  (0) 2023.01.17
[Laravel] Laravel Sail 설치하기  (0) 2021.09.23