Last active
August 29, 2015 13:57
-
-
Save AndrewGreen/9846282 to your computer and use it in GitHub Desktop.
Idea for PHP typesafe enum
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* To create some typesafe enums, just extend this class, declare some static | |
* properties, then call YourClassName::setUp(). Example follows. | |
* | |
* Disadvantages: | |
* - Since the enums are public properties, they could be modified by | |
* mistake (or intentionally by malicious code). | |
* - YourClassName::setUp() must be called. | |
* - $ required in front of enum name. | |
* | |
* Advantages: | |
* - IDE autocompletion should work. | |
*/ | |
abstract class TypesafeEnum { | |
private $name; | |
public static function setUp() { | |
$calledClassName = get_called_class(); | |
$calledClass = new ReflectionClass( $calledClassName ); | |
$props = $calledClass->getProperties( ReflectionProperty::IS_STATIC ); | |
foreach ( $props as $prop ) { | |
$prop->setValue( new $calledClassName( $prop->getName() ) ); | |
} | |
} | |
private function __construct( $name ) { | |
$this->name = $name; | |
} | |
public function __toString() { | |
return $this->name; | |
} | |
} | |
// Example use | |
final class MyHappyEnum extends TypesafeEnum { | |
// Don't initialize these, just declare them. | |
static $ENUM_ONE; | |
static $ENUM_TWO; | |
static $ENUM_THREE; | |
} | |
// Gotta call this somewhere, but only once. Could put it in the same file as | |
// the concrete class, I think. | |
MyHappyEnum::setUp(); | |
// Here's the function we'll use to demonstrate | |
$func = function( MyHappyEnum $enum ) { | |
// Got the right class | |
print 'Class of parameter is ' . get_class( $enum ) . "\n"; | |
// __toString() works | |
print 'Name is ' . $enum . "\n"; | |
// Switch also works normally | |
switch ( $enum ) { | |
case MyHappyEnum::$ENUM_ONE: | |
print "Switch: one\n"; | |
break; | |
case MyHappyEnum::$ENUM_TWO: | |
print "Switch: two\n"; | |
break; | |
case MyHappyEnum::$ENUM_THREE: | |
print "Switch: three\n"; | |
break; | |
default: | |
throw new Exception( "Shouldn't happen." ); | |
} | |
}; | |
print ( "Testing call with " . MyHappyEnum::$ENUM_TWO . "\n\n" ); | |
$func( MyHappyEnum::$ENUM_TWO ); | |
print ( "\n\nTesting call with " . MyHappyEnum::$ENUM_THREE . "\n\n" ); | |
$func( MyHappyEnum::$ENUM_THREE ); | |
// All of these cause a fatal error. Uncomment any one to try it. | |
// $func( new MyHappyEnum( 'Can\'t instantiate anywhere else.' ) ); | |
// $func( 'Type hint prevents passing anything else.' ); | |
// $func( MyHappyEnum::$CAN_T_USE_NON_EXISTENT_ENUM ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Compare with https://gist.github.com/AndrewGreen/9866433