프로그래밍 언어/PHP

PHP의 enumerations

Rateye 2021. 7. 7. 10:10
728x90
반응형

 

질문 : PHP의 enumerations

PHP에는 아직 네이티브 열거 형이 없다는 것을 알고 있습니다. 하지만 저는 자바 세계에서 익숙해졌습니다. IDE의 자동 완성 기능이 이해할 수있는 미리 정의 된 값을 제공하는 방법으로 열거 형을 사용하고 싶습니다.

상수가 트릭을 수행하지만 네임 스페이스 충돌 문제가 있고 (또는 실제로는 왜냐하면 ) 전역 적입니다. 배열에는 네임 스페이스 문제가 없지만 너무 모호하고 런타임에 덮어 쓸 수 있으며 IDE는 추가 정적 분석 주석이나 속성없이 키를 자동으로 채우는 방법을 거의 알지 못합니다.

일반적으로 사용하는 솔루션 / 해결 방법이 있습니까? PHP 녀석이 열거에 대해 생각이나 결정을 내 렸는지 기억하는 사람이 있습니까?

답변

사용 사례에 따라 일반적으로 다음과 같은 간단한 것을 사용합니다.

abstract class DaysOfWeek
{
    const Sunday = 0;
    const Monday = 1;
    // etc.
}

$today = DaysOfWeek::Sunday;

그러나 다른 사용 사례에서는 상수 및 값에 대한 더 많은 검증이 필요할 수 있습니다. 아래의 성찰에 대한 의견과 몇 가지 다른 참고 사항을 바탕으로 훨씬 더 광범위한 사례에 더 잘 부합 할 수있는 확장 된 예가 있습니다.

abstract class BasicEnum {
    private static $constCacheArray = NULL;

    private static function getConstants() {
        if (self::$constCacheArray == NULL) {
            self::$constCacheArray = [];
        }
        $calledClass = get_called_class();
        if (!array_key_exists($calledClass, self::$constCacheArray)) {
            $reflect = new ReflectionClass($calledClass);
            self::$constCacheArray[$calledClass] = $reflect->getConstants();
        }
        return self::$constCacheArray[$calledClass];
    }

    public static function isValidName($name, $strict = false) {
        $constants = self::getConstants();

        if ($strict) {
            return array_key_exists($name, $constants);
        }

        $keys = array_map('strtolower', array_keys($constants));
        return in_array(strtolower($name), $keys);
    }

    public static function isValidValue($value, $strict = true) {
        $values = array_values(self::getConstants());
        return in_array($value, $values, $strict);
    }
}

BasicEnum을 확장하는 간단한 enum 클래스를 만들면 이제 간단한 입력 유효성 검사를 위해 메서드를 사용할 수 있습니다.

abstract class DaysOfWeek extends BasicEnum {
    const Sunday = 0;
    const Monday = 1;
    const Tuesday = 2;
    const Wednesday = 3;
    const Thursday = 4;
    const Friday = 5;
    const Saturday = 6;
}

DaysOfWeek::isValidName('Humpday');                  // false
DaysOfWeek::isValidName('Monday');                   // true
DaysOfWeek::isValidName('monday');                   // true
DaysOfWeek::isValidName('monday', $strict = true);   // false
DaysOfWeek::isValidName(0);                          // false

DaysOfWeek::isValidValue(0);                         // true
DaysOfWeek::isValidValue(5);                         // true
DaysOfWeek::isValidValue(7);                         // false
DaysOfWeek::isValidValue('Friday');                  // false

참고로, 데이터가 변경되지 않는 정적 / 상수 클래스 (예 : 열거 형)에서 리플렉션을 한 번 이상 사용할 때마다 새 리플렉션 개체를 사용하기 때문에 해당 리플렉션 호출의 결과를 캐시합니다. 결국 눈에 띄는 성능 영향을 미칩니다 (여러 열거 형에 대해 연관 배열에 저장 됨).

대부분의 사람들이 마침내 5.3 이상 SplEnum 을 사용할 수 있으므로 코드베이스 전체에서 실제 열거 형 인스턴스화가 있다는 전통적으로 직관적이지 않은 개념에 신경 쓰지 않는 한, 이는 확실히 실행 가능한 옵션입니다. 위의 예에서 BasicEnumDaysOfWeek 는 인스턴스화 할 수 없으며 인스턴스화 할 수도 없습니다.

출처 : https://stackoverflow.com/questions/254514/enumerations-on-php
728x90
반응형