@@ -30,12 +30,19 @@ abstract class Enum
30
30
private $ ordinal ;
31
31
32
32
/**
33
- * An array of available constants by class
33
+ * A map of enumerator names and values by enumeration class
34
34
*
35
35
* @var array ["$class" => ["$name" => $value, ...], ...]
36
36
*/
37
37
private static $ constants = array ();
38
38
39
+ /**
40
+ * A List of of available enumerator names by enumeration class
41
+ *
42
+ * @var array ["$class" => ["$name0", ...], ...]
43
+ */
44
+ private static $ names = array ();
45
+
39
46
/**
40
47
* Already instantiated enumerators
41
48
*
@@ -110,6 +117,9 @@ final public function getValue()
110
117
*/
111
118
final public function getName ()
112
119
{
120
+ if ($ this ->ordinal !== null ) {
121
+ return self ::$ names [static ::class][$ this ->ordinal ];
122
+ }
113
123
return array_search ($ this ->value , self ::detectConstants (static ::class), true );
114
124
}
115
125
@@ -235,21 +245,25 @@ final public static function byOrdinal($ordinal)
235
245
{
236
246
$ ordinal = (int ) $ ordinal ;
237
247
$ class = static ::class;
238
- $ constants = self ::detectConstants ($ class );
239
- $ item = array_slice ($ constants , $ ordinal , 1 , true );
240
- if (empty ($ item )) {
248
+
249
+ if (!isset (self ::$ names [$ class ])) {
250
+ self ::detectConstants ($ class );
251
+ }
252
+
253
+ if (!isset (self ::$ names [$ class ][$ ordinal ])) {
241
254
throw new InvalidArgumentException (sprintf (
242
255
'Invalid ordinal number, must between 0 and %s ' ,
243
- count ($ constants ) - 1
256
+ count (self :: $ names [ $ class ] ) - 1
244
257
));
245
258
}
246
259
247
- $ name = key ( $ item ) ;
260
+ $ name = self :: $ names [ $ class ][ $ ordinal ] ;
248
261
if (isset (self ::$ instances [$ class ][$ name ])) {
249
262
return self ::$ instances [$ class ][$ name ];
250
263
}
251
264
252
- return self ::$ instances [$ class ][$ name ] = new $ class (current ($ item ), $ ordinal );
265
+ $ const = $ class . ':: ' . $ name ;
266
+ return self ::$ instances [$ class ][$ name ] = new $ class (constant ($ const ));
253
267
}
254
268
255
269
/**
@@ -259,7 +273,10 @@ final public static function byOrdinal($ordinal)
259
273
*/
260
274
final public static function getEnumerators ()
261
275
{
262
- return array_map ([static ::class, 'byName ' ], array_keys (self ::detectConstants (static ::class)));
276
+ if (!isset (self ::$ names [static ::class])) {
277
+ self ::detectConstants (static ::class);
278
+ }
279
+ return array_map ([static ::class, 'byName ' ], self ::$ names [static ::class]);
263
280
}
264
281
265
282
/**
@@ -279,7 +296,10 @@ final public static function getValues()
279
296
*/
280
297
final public static function getNames ()
281
298
{
282
- return array_keys (self ::detectConstants (static ::class));
299
+ if (!isset (self ::$ names [static ::class])) {
300
+ self ::detectConstants (static ::class);
301
+ }
302
+ return self ::$ names [static ::class];
283
303
}
284
304
/*
285
305
* Get a list of enumerator ordinal numbers
@@ -320,7 +340,7 @@ final public static function has($value)
320
340
}
321
341
322
342
/**
323
- * Detect all available constants by the given class
343
+ * Detect all public available constants of given enumeration class
324
344
*
325
345
* @param string $class
326
346
* @return array
@@ -368,6 +388,7 @@ private static function detectConstants($class)
368
388
}
369
389
370
390
self ::$ constants [$ class ] = $ constants ;
391
+ self ::$ names [$ class ] = array_keys ($ constants );
371
392
}
372
393
373
394
return self ::$ constants [$ class ];
0 commit comments