©
This document uses PHP Chinese website manual Release
(PECL spl_types >= 0.1.0)
SplEnum gives the ability to emulate and create enumeration objects natively in PHP.
$include_default
= false
] )$initial_value
[, bool $strict
]] )SplEnum::__default
Example #1 SplEnum usage example
<?php
class Month extends SplEnum {
const __default = self :: January ;
const January = 1 ;
const February = 2 ;
const March = 3 ;
const April = 4 ;
const May = 5 ;
const June = 6 ;
const July = 7 ;
const August = 8 ;
const September = 9 ;
const October = 10 ;
const November = 11 ;
const December = 12 ;
}
echo new Month ( Month :: June ) . PHP_EOL ;
try {
new Month ( 13 );
} catch ( UnexpectedValueException $uve ) {
echo $uve -> getMessage () . PHP_EOL ;
}
?>
以上例程会输出:
6 Value not a const in enum Month
[#1] dc at dcitservices dot com dot au [2015-11-27 04:19:48]
I use the following function getValue() to have a dynamically way to check and retrieve value without errors.
class MyEnum extends SplEnum
{
const __default = 0;
const C1 = 1;
const C2 = 2;
public function getValue($key)
{
$declaredElems = $this->getConstList();
if(array_key_exists($key, $declaredElems)){
$r = new \ReflectionClass($this);
return $r->getConstant($key);
}else{
return self::__default;
}
}
}
[#2] mohanrajnr at gmail dot com [2015-05-09 11:16:54]
if class SplEnum is not present, I would normally use something simple like the following:
abstract class DaysOfWeek
{
const Sunday = 0;
const Monday = 1;
// etc.
}
$today = DaysOfWeek::Sunday;
However, other use cases may require more validation of constants and values.
abstract class BasicEnum {
private static $constCacheArray = NULL;
private function __construct(){
}
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) {
$values = array_values(self::getConstants());
return in_array($value, $values, $strict = true);
}
}
By creating a simple enum class that extends BasicEnum, you now have the ability to use methods thusly for simple input validation:
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
As a side note, any time I use reflection at least once on a static/const class where the data won't change (such as in an enum), I cache the results of those reflection calls, since using fresh reflection objects each time will eventually have a noticeable performance impact (Stored in an assocciative array for multiple enums).
[#3] lsloan-php dot net at umich dot edu [2014-12-12 20:11:11]
SplEnum is a nice start for enumerated type support as an extension (making enum a part of the language would be much better), but it lacks a lot of features that enums have in other languages. I needed functionality like the hasKey() method supported by Java. I extended the class as SplEnumPlus and used that subclass in my code as follows:
<?php
class SplEnumPlus extends SplEnum {
static function hasKey($key) {
$foundKey = false;
try {
$enumClassName = get_called_class();
new $enumClassName($key);
$foundKey = true;
} finally {
return $foundKey;
}
}
}
class Fruit extends SplEnumPlus {
const APPLE = 1;
const ORANGE = 2;
}
echo (Fruit::hasKey(Fruit::APPLE) ? 'yes' : 'no') . PHP_EOL; // yes
echo (Fruit::hasKey('banana') ? 'yes' : 'no') . PHP_EOL; // no
?>
Other useful features, like reverse value-to-key lookups, could be done in this way. It would be helpful if this and other useful functionality were made part of SplEnum.
[#4] No Such Alias [2010-07-30 09:11:37]
Here's a clearer example usage in case anyone else finds the
current documentation confusing (as I did).
<?php
class Fruit extends SplEnum
{
// If no value is given during object construction this value is used
const __default = 1;
// Our enum values
const APPLE = 1;
const ORANGE = 2;
}
$myApple = new Fruit();
$myOrange = new Fruit(Fruit::ORANGE);
$fail = 1;
function eat(Fruit $aFruit)
{
if (Fruit::APPLE == $aFruit) {
echo "Eating an apple.\n";
} elseif (Fruit::ORANGE == $aFruit) {
echo "Eating an orange.\n";
}
}
eat($myApple); // Eating an apple.
eat($myOrange); // Eating an orange.
eat($fail); // PHP Catchable fatal error: Argument 1 passed to eat() must be an instance of Fruit, integer given
?>