根据使用情况,我通常会使用类似以下的 简单 内容:
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'); // falseDaysOfWeek::isValidName('Monday'); // trueDaysOfWeek::isValidName('monday'); // trueDaysOfWeek::isValidName('monday', $strict = true); // falseDaysOfWeek::isValidName(0); // falseDaysOfWeek::isValidValue(0); // trueDaysOfWeek::isValidValue(5); // trueDaysOfWeek::isValidValue(7); // falseDaysOfWeek::isValidValue('Friday'); // false附带说明一下,任何时候我在 不会更改数据的静态/ const类上
至少使用一次反射(例如在枚举中)时,都会缓存这些反射调用的结果,因为每次都使用新的反射对象最终将对性能产生显着影响(存储在多个枚举的关联数组中)。
现在,大多数人 终于 升级到了至少5.3,并且
SplEnum可以使用,这当然也是一个可行的选择-只要您不介意在整个代码库中具有实际枚举 实例
的传统不直观的概念。在上面的示例中,
BasicEnumand
DaysOfWeek根本不能实例化,也不应该实例化。



