Skip to content

Commit 5eca803

Browse files
committed
Always return the same instance of a const
Implement EnumManager to keep track of all instances
1 parent e42fa9d commit 5eca803

File tree

3 files changed

+74
-4
lines changed

3 files changed

+74
-4
lines changed

src/Enum.php

+20-4
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,21 @@ public static function search($value)
165165
return array_search($value, static::toArray(), true);
166166
}
167167

168+
/**
169+
* Returns Enum by key
170+
*
171+
* @return static
172+
*/
173+
public static function fromKey($name)
174+
{
175+
$array = static::toArray();
176+
if (array_key_exists($name, $array)) {
177+
return EnumManager::get(new static($array[$name]));
178+
}
179+
180+
return null;
181+
}
182+
168183
/**
169184
* Returns a value when called statically like so: MyEnum::SOME_VALUE() given SOME_VALUE is a class constant
170185
*
@@ -176,11 +191,12 @@ public static function search($value)
176191
*/
177192
public static function __callStatic($name, $arguments)
178193
{
179-
$array = static::toArray();
180-
if (isset($array[$name])) {
181-
return new static($array[$name]);
194+
$result = static::fromKey($name);
195+
196+
if ($result === null) {
197+
throw new \BadMethodCallException("No static method or enum constant '$name' in class " . get_called_class());
182198
}
183199

184-
throw new \BadMethodCallException("No static method or enum constant '$name' in class " . get_called_class());
200+
return $result;
185201
}
186202
}

src/EnumManager.php

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
/**
3+
* @link http://github.com/myclabs/php-enum
4+
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
5+
*/
6+
7+
namespace MyCLabs\Enum;
8+
9+
use ReflectionObject;
10+
11+
/**
12+
* Enum instance manager
13+
*
14+
* @internal
15+
*/
16+
abstract class EnumManager
17+
{
18+
/**
19+
* Store existing Enum instances.
20+
*
21+
* @var array
22+
*/
23+
private static $instances = array();
24+
25+
/**
26+
* Returns the Enum instance for the given prototype
27+
*
28+
* @return Enum
29+
*/
30+
public static function get(Enum $enum)
31+
{
32+
$reflection = new ReflectionObject($enum);
33+
$class = $reflection->getName();
34+
$name = $enum->getKey();
35+
36+
if (isset(self::$instances[$class][$name])) {
37+
return self::$instances[$class][$name];
38+
}
39+
40+
self::$instances[$class][$name] = $enum;
41+
return $enum;
42+
}
43+
}

tests/EnumTest.php

+11
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,17 @@ public function testEquals()
228228
$this->assertTrue($foo->equals($anotherFoo));
229229
}
230230

231+
/**
232+
* __callStatic()
233+
*/
234+
public function testSameInstance()
235+
{
236+
$foo1 = EnumFixture::FOO();
237+
$foo2 = EnumFixture::FOO();
238+
239+
$this->assertSame($foo1, $foo2);
240+
}
241+
231242
/**
232243
* equals()
233244
*/

0 commit comments

Comments
 (0)