PHP和枚举

我知道PHP没有本地枚举。 但是我已经习惯了来自Java世界的他们。 我很乐意使用枚举作为给出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的简单枚举类,您现在可以使用方法来进行简单的输入验证:

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根本无法实例化,也不应该这样做。


还有一个本地扩展。 SplEnum

SplEnum提供了在PHP中本地模拟和创建枚举对象的能力。

http://www.php.net/manual/en/class.splenum.php


类常量呢?

<?php

class YourClass
{
    const SOME_CONSTANT = 1;

    public function echoConstant()
    {
        echo self::SOME_CONSTANT;
    }
}

echo YourClass::SOME_CONSTANT;

$c = new YourClass;
$c->echoConstant();
链接地址: http://www.djcxy.com/p/4923.html

上一篇: PHP and Enumerations

下一篇: How to check if PHP array is associative or sequential?