@@ -130,9 +130,10 @@ final public function getName()
130130 final public function getOrdinal ()
131131 {
132132 if ($ this ->ordinal === null ) {
133- $ ordinal = 0 ;
134- $ value = $ this ->value ;
135- foreach (self ::detectConstants (static ::class) as $ constValue ) {
133+ $ ordinal = 0 ;
134+ $ value = $ this ->value ;
135+ $ constants = self ::$ constants [static ::class] ?? static ::getConstants ();
136+ foreach ($ constants as $ constValue ) {
136137 if ($ value === $ constValue ) {
137138 break ;
138139 }
@@ -189,8 +190,7 @@ final public static function get($enumerator)
189190 */
190191 final public static function byValue ($ value )
191192 {
192- $ constants = self ::$ constants [static ::class]
193- ?? self ::detectConstants (static ::class);
193+ $ constants = self ::$ constants [static ::class] ?? static ::getConstants ();
194194
195195 $ name = \array_search ($ value , $ constants , true );
196196 if ($ name === false ) {
@@ -239,7 +239,7 @@ final public static function byName(string $name)
239239 */
240240 final public static function byOrdinal (int $ ordinal )
241241 {
242- $ constants = self ::$ constants [static ::class] ?? self :: detectConstants ( static ::class );
242+ $ constants = self ::$ constants [static ::class] ?? static ::getConstants ( );
243243
244244 if (!isset (self ::$ names [static ::class][$ ordinal ])) {
245245 throw new InvalidArgumentException (\sprintf (
@@ -262,7 +262,7 @@ final public static function byOrdinal(int $ordinal)
262262 final public static function getEnumerators ()
263263 {
264264 if (!isset (self ::$ names [static ::class])) {
265- self :: detectConstants ( static ::class );
265+ static ::getConstants ( );
266266 }
267267 return \array_map ([static ::class, 'byName ' ], self ::$ names [static ::class]);
268268 }
@@ -274,7 +274,7 @@ final public static function getEnumerators()
274274 */
275275 final public static function getValues ()
276276 {
277- return \array_values (self ::detectConstants ( static ::class));
277+ return \array_values (self ::$ constants [ static ::class] ?? static :: getConstants ( ));
278278 }
279279
280280 /**
@@ -285,7 +285,7 @@ final public static function getValues()
285285 final public static function getNames ()
286286 {
287287 if (!isset (self ::$ names [static ::class])) {
288- self :: detectConstants ( static ::class );
288+ static ::getConstants ( );
289289 }
290290 return self ::$ names [static ::class];
291291 }
@@ -297,7 +297,7 @@ final public static function getNames()
297297 */
298298 final public static function getOrdinals ()
299299 {
300- $ count = \count (self ::detectConstants ( static ::class));
300+ $ count = \count (self ::$ constants [ static ::class] ?? static :: getConstants ( ));
301301 return $ count ? \range (0 , $ count - 1 ) : [];
302302 }
303303
@@ -309,7 +309,49 @@ final public static function getOrdinals()
309309 */
310310 final public static function getConstants ()
311311 {
312- return self ::detectConstants (static ::class);
312+ if (isset (self ::$ constants [static ::class])) {
313+ return self ::$ constants [static ::class];
314+ }
315+
316+ $ reflection = new ReflectionClass (static ::class);
317+ $ constants = [];
318+
319+ do {
320+ $ scopeConstants = [];
321+ // Enumerators must be defined as public class constants
322+ foreach ($ reflection ->getReflectionConstants () as $ reflConstant ) {
323+ if ($ reflConstant ->isPublic ()) {
324+ $ scopeConstants [ $ reflConstant ->getName () ] = $ reflConstant ->getValue ();
325+ }
326+ }
327+
328+ $ constants = $ scopeConstants + $ constants ;
329+ } while (($ reflection = $ reflection ->getParentClass ()) && $ reflection ->name !== __CLASS__ );
330+
331+ assert (
332+ self ::noAmbiguousValues ($ constants ),
333+ 'Ambiguous enumerator values detected for ' . static ::class
334+ );
335+
336+ self ::$ names [static ::class] = \array_keys ($ constants );
337+ return self ::$ constants [static ::class] = $ constants ;
338+ }
339+
340+ /**
341+ * Test that the given constants does not contain ambiguous values
342+ * @param array $constants
343+ * @return bool
344+ */
345+ private static function noAmbiguousValues ($ constants )
346+ {
347+ foreach ($ constants as $ value ) {
348+ $ names = \array_keys ($ constants , $ value , true );
349+ if (\count ($ names ) > 1 ) {
350+ return false ;
351+ }
352+ }
353+
354+ return true ;
313355 }
314356
315357 /**
@@ -332,8 +374,7 @@ final public static function has($enumerator)
332374 */
333375 final public static function hasValue ($ value )
334376 {
335- $ constants = self ::detectConstants (static ::class);
336- return \in_array ($ value , $ constants , true );
377+ return \in_array ($ value , self ::$ constants [static ::class] ?? static ::getConstants (), true );
337378 }
338379
339380 /**
@@ -347,59 +388,6 @@ final public static function hasName(string $name)
347388 return \defined ("static:: {$ name }" );
348389 }
349390
350- /**
351- * Detect all public available constants of given enumeration class
352- *
353- * @param string $class
354- * @return array
355- */
356- private static function detectConstants ($ class )
357- {
358- if (!isset (self ::$ constants [$ class ])) {
359- $ reflection = new ReflectionClass ($ class );
360- $ constants = [];
361-
362- do {
363- $ scopeConstants = [];
364- // Enumerators must be defined as public class constants
365- foreach ($ reflection ->getReflectionConstants () as $ reflConstant ) {
366- if ($ reflConstant ->isPublic ()) {
367- $ scopeConstants [ $ reflConstant ->getName () ] = $ reflConstant ->getValue ();
368- }
369- }
370-
371- $ constants = $ scopeConstants + $ constants ;
372- } while (($ reflection = $ reflection ->getParentClass ()) && $ reflection ->name !== __CLASS__ );
373-
374- assert (
375- self ::noAmbiguousValues ($ constants ),
376- "Ambiguous enumerator values detected for {$ class }"
377- );
378-
379- self ::$ constants [$ class ] = $ constants ;
380- self ::$ names [$ class ] = \array_keys ($ constants );
381- }
382-
383- return self ::$ constants [$ class ];
384- }
385-
386- /**
387- * Test that the given constants does not contain ambiguous values
388- * @param array $constants
389- * @return bool
390- */
391- private static function noAmbiguousValues ($ constants )
392- {
393- foreach ($ constants as $ value ) {
394- $ names = \array_keys ($ constants , $ value , true );
395- if (\count ($ names ) > 1 ) {
396- return false ;
397- }
398- }
399-
400- return true ;
401- }
402-
403391 /**
404392 * Get an enumerator instance by the given name.
405393 *
0 commit comments