文字

The SplEnum class

(PECL spl_types >= 0.1.0)

简介

SplEnum gives the ability to emulate and create enumeration objects natively in PHP.

类摘要

SplEnum extends SplType {
const NULL __default = null ;
public array getConstList ([ bool $include_default = false ] )
SplType::__construct ([ mixed $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

Table of Contents

  • SplEnum::getConstList — Returns all consts (possible values) as an array.

用户评论:

[#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

?>

上一篇: 下一篇: