Skip to content

Commit 2a9acc7

Browse files
authored
Merge pull request #132 from marc-mabe/micro-optimizations
Micro optimizations
2 parents 777a804 + 83b2508 commit 2a9acc7

File tree

3 files changed

+65
-87
lines changed

3 files changed

+65
-87
lines changed

bench/EnumBench.php renamed to bench/AbstractEnumBench.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* @copyright Copyright (c) 2019 Marc Bennewitz
1919
* @license http://github.com/marc-mabe/php-enum/blob/master/LICENSE.txt New BSD License
2020
*/
21-
class EnumBench
21+
class AbstractEnumBench
2222
{
2323
/**
2424
* @var ReflectionProperty[]

src/Enum.php

Lines changed: 59 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*

tests/MabeEnumTest/EnumSerializableTraitTest.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use MabeEnumTest\TestAsset\SerializableEnum;
99
use PHPUnit\Framework\TestCase;
1010
use ReflectionClass;
11+
use ReflectionProperty;
1112
use RuntimeException;
1213

1314
/**
@@ -89,11 +90,9 @@ private function clearEnumeration($enumeration)
8990
$reflClass = $reflClass->getParentClass();
9091
}
9192

92-
$reflPropInstances = $reflClass->getProperty('instances');
93-
$reflPropInstances->setAccessible(true);
94-
$reflPropInstances->setValue(null, array());
95-
$reflPropConstants = $reflClass->getProperty('constants');
96-
$reflPropConstants->setAccessible(true);
97-
$reflPropConstants->setValue(null, array());
93+
foreach ($reflClass->getProperties(ReflectionProperty::IS_STATIC) as $reflProp) {
94+
$reflProp->setAccessible(true);;
95+
$reflProp->setValue(null, []);
96+
}
9897
}
9998
}

0 commit comments

Comments
 (0)