@@ -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,11 +190,9 @@ final public static function get($enumerator)
189190 */
190191 final public static function byValue ($ value )
191192 {
192- if (!isset (self ::$ constants [static ::class])) {
193- self ::detectConstants (static ::class);
194- }
193+ $ constants = self ::$ constants [static ::class] ?? static ::getConstants ();
195194
196- $ name = \array_search ($ value , self :: $ constants[ static ::class] , true );
195+ $ name = \array_search ($ value , $ constants , true );
197196 if ($ name === false ) {
198197 throw new InvalidArgumentException (sprintf (
199198 'Unknown value %s for enumeration %s ' ,
@@ -204,11 +203,8 @@ final public static function byValue($value)
204203 ));
205204 }
206205
207- if (!isset (self ::$ instances [static ::class][$ name ])) {
208- self ::$ instances [static ::class][$ name ] = new static (self ::$ constants [static ::class][$ name ]);
209- }
210-
211- return self ::$ instances [static ::class][$ name ];
206+ return self ::$ instances [static ::class][$ name ]
207+ ?? self ::$ instances [static ::class][$ name ] = new static ($ constants [$ name ]);
212208 }
213209
214210 /**
@@ -243,9 +239,7 @@ final public static function byName(string $name)
243239 */
244240 final public static function byOrdinal (int $ ordinal )
245241 {
246- if (!isset (self ::$ names [static ::class])) {
247- self ::detectConstants (static ::class);
248- }
242+ $ constants = self ::$ constants [static ::class] ?? static ::getConstants ();
249243
250244 if (!isset (self ::$ names [static ::class][$ ordinal ])) {
251245 throw new InvalidArgumentException (\sprintf (
@@ -256,11 +250,8 @@ final public static function byOrdinal(int $ordinal)
256250 }
257251
258252 $ name = self ::$ names [static ::class][$ ordinal ];
259- if (isset (self ::$ instances [static ::class][$ name ])) {
260- return self ::$ instances [static ::class][$ name ];
261- }
262-
263- return self ::$ instances [static ::class][$ name ] = new static (self ::$ constants [static ::class][$ name ], $ ordinal );
253+ return self ::$ instances [static ::class][$ name ]
254+ ?? self ::$ instances [static ::class][$ name ] = new static ($ constants [$ name ], $ ordinal );
264255 }
265256
266257 /**
@@ -271,7 +262,7 @@ final public static function byOrdinal(int $ordinal)
271262 final public static function getEnumerators ()
272263 {
273264 if (!isset (self ::$ names [static ::class])) {
274- self :: detectConstants ( static ::class );
265+ static ::getConstants ( );
275266 }
276267 return \array_map ([static ::class, 'byName ' ], self ::$ names [static ::class]);
277268 }
@@ -283,7 +274,7 @@ final public static function getEnumerators()
283274 */
284275 final public static function getValues ()
285276 {
286- return \array_values (self ::detectConstants ( static ::class));
277+ return \array_values (self ::$ constants [ static ::class] ?? static :: getConstants ( ));
287278 }
288279
289280 /**
@@ -294,7 +285,7 @@ final public static function getValues()
294285 final public static function getNames ()
295286 {
296287 if (!isset (self ::$ names [static ::class])) {
297- self :: detectConstants ( static ::class );
288+ static ::getConstants ( );
298289 }
299290 return self ::$ names [static ::class];
300291 }
@@ -306,7 +297,7 @@ final public static function getNames()
306297 */
307298 final public static function getOrdinals ()
308299 {
309- $ count = \count (self ::detectConstants ( static ::class));
300+ $ count = \count (self ::$ constants [ static ::class] ?? static :: getConstants ( ));
310301 return $ count ? \range (0 , $ count - 1 ) : [];
311302 }
312303
@@ -318,7 +309,49 @@ final public static function getOrdinals()
318309 */
319310 final public static function getConstants ()
320311 {
321- 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 ;
322355 }
323356
324357 /**
@@ -341,8 +374,7 @@ final public static function has($enumerator)
341374 */
342375 final public static function hasValue ($ value )
343376 {
344- $ constants = self ::detectConstants (static ::class);
345- return \in_array ($ value , $ constants , true );
377+ return \in_array ($ value , self ::$ constants [static ::class] ?? static ::getConstants (), true );
346378 }
347379
348380 /**
@@ -356,59 +388,6 @@ final public static function hasName(string $name)
356388 return \defined ("static:: {$ name }" );
357389 }
358390
359- /**
360- * Detect all public available constants of given enumeration class
361- *
362- * @param string $class
363- * @return array
364- */
365- private static function detectConstants ($ class )
366- {
367- if (!isset (self ::$ constants [$ class ])) {
368- $ reflection = new ReflectionClass ($ class );
369- $ constants = [];
370-
371- do {
372- $ scopeConstants = [];
373- // Enumerators must be defined as public class constants
374- foreach ($ reflection ->getReflectionConstants () as $ reflConstant ) {
375- if ($ reflConstant ->isPublic ()) {
376- $ scopeConstants [ $ reflConstant ->getName () ] = $ reflConstant ->getValue ();
377- }
378- }
379-
380- $ constants = $ scopeConstants + $ constants ;
381- } while (($ reflection = $ reflection ->getParentClass ()) && $ reflection ->name !== __CLASS__ );
382-
383- assert (
384- self ::noAmbiguousValues ($ constants ),
385- "Ambiguous enumerator values detected for {$ class }"
386- );
387-
388- self ::$ constants [$ class ] = $ constants ;
389- self ::$ names [$ class ] = \array_keys ($ constants );
390- }
391-
392- return self ::$ constants [$ class ];
393- }
394-
395- /**
396- * Test that the given constants does not contain ambiguous values
397- * @param array $constants
398- * @return bool
399- */
400- private static function noAmbiguousValues ($ constants )
401- {
402- foreach ($ constants as $ value ) {
403- $ names = \array_keys ($ constants , $ value , true );
404- if (\count ($ names ) > 1 ) {
405- return false ;
406- }
407- }
408-
409- return true ;
410- }
411-
412391 /**
413392 * Get an enumerator instance by the given name.
414393 *
0 commit comments