Created
August 9, 2018 22:17
-
-
Save Cxarli/c175a73240fa4b51f3c0990a6ba83301 to your computer and use it in GitHub Desktop.
Enum implementation in PHP
This file contains hidden or 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 | |
abstract class Enum { | |
private static $cache = []; | |
// Helper function to load the required fields into the cache. | |
private static function loadCache(): void { | |
// Create cache for enum | |
self::$cache[static::class] = []; | |
// Get all constants | |
$refl = new \ReflectionClass(static::class); | |
$consts = $refl->getConstants(); | |
// Store constants in cache | |
// NOTE: The value of the constant is ignored | |
foreach (array_keys($consts) as $i => $key) { | |
self::$cache[static::class][$key] = new static($i, $key); | |
} | |
} | |
// Enum::A() should give Enum::$cache[Enum::A] | |
public static function __callStatic(string $name, $_): self { | |
// Make sure the cache is loaded | |
if (! isset(self::$cache[static::class])) { | |
static::loadCache(); | |
} | |
// Check if key exists | |
if (! isset(self::$cache[static::class][$name])) { | |
throw new \Exception("Invalid key: '$name'"); | |
return null; | |
} | |
// Return item from cache | |
return self::$cache[static::class][$name]; | |
} | |
// Enum::from('A') should give Enum::$cache[Enum::A] | |
public static function from(string $key): self { | |
return static::$key(); | |
} | |
private $val; | |
private $name; | |
private function __construct(int $val, string $name) { | |
$this->val = $val; | |
$this->name = $name; | |
} | |
public function __toString(): string { | |
return static::class . ' {' . $this->name . '}'; | |
} | |
public function name(): string { | |
return $this->name; | |
} | |
public function val(): int { | |
return $this->val; | |
} | |
public function __debugInfo(): array { | |
return [ | |
'name' => $this->name, | |
'val' => $this->val, | |
]; | |
} | |
} | |
class Month extends Enum { | |
const January = null; | |
const February = null; | |
const March = null; | |
const April = null; | |
const May = null; | |
const June = null; | |
const July = null; | |
const August = null; | |
const September = null; | |
const October = null; | |
const November = null; | |
const December = null; | |
} | |
class Weekday extends Enum { | |
const Monday = null; | |
const Tuesday = null; | |
const Wednesday = null; | |
const Thursday = null; | |
const Friday = null; | |
const Saturday = null; | |
const Sunday = null; | |
} | |
function planDate(Month $month, Weekday $day) { | |
if (( | |
// month between january and april | |
Month::January()->val() <= $month->val() | |
&& $month->val() <= Month::April()->val() | |
) || ( | |
// month between october and december | |
Month::October()->val() <= $month->val() | |
&& $month->val() <= Month::December()->val() | |
)) | |
{ | |
return "Sorry, but then it's too cold outside."; | |
} | |
if ($day == Weekday::Friday()) { | |
return "Sorry, I already have an important meeting."; | |
} | |
return "A " . $day->name() . " in " . $month->name() . " sounds nice!"; | |
} | |
echo planDate(Month::March(), Weekday::Monday()) . "\n"; | |
echo planDate(Month::from("August"), Weekday::Friday()) . "\n"; | |
echo planDate(Month::from("June"), Weekday::from("Sunday")) . "\n"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment