@@ -47,16 +47,10 @@ abstract class Enum
47
47
* @throws InvalidArgumentException On an unknwon or invalid value
48
48
* @throws LogicException On ambiguous constant values
49
49
*/
50
- final private function __construct ($ value )
50
+ final private function __construct ($ value, $ ordinal = null )
51
51
{
52
- // find and set the given value
53
- // set the defined value because of non strict comparison
54
- $ constants = static ::getConstants ();
55
- $ const = array_search ($ value , $ constants );
56
- if ($ const === false ) {
57
- throw new InvalidArgumentException ("Unknown value ' {$ value }' " );
58
- }
59
- $ this ->value = $ constants [$ const ];
52
+ $ this ->value = $ value ;
53
+ $ this ->ordinal = $ ordinal ;
60
54
}
61
55
62
56
/**
@@ -93,7 +87,7 @@ final public function getValue()
93
87
*/
94
88
final public function getName ()
95
89
{
96
- return array_search ($ this ->value , $ this :: getConstants ( ), true );
90
+ return array_search ($ this ->value , self :: detectConstants ( get_called_class () ), true );
97
91
}
98
92
99
93
/**
@@ -109,7 +103,7 @@ final public function getOrdinal()
109
103
// detect ordinal
110
104
$ ordinal = 0 ;
111
105
$ value = $ this ->value ;
112
- foreach (static :: getConstants ( ) as $ constValue ) {
106
+ foreach (self :: detectConstants ( get_called_class () ) as $ constValue ) {
113
107
if ($ value === $ constValue ) {
114
108
break ;
115
109
}
@@ -135,9 +129,14 @@ final static public function get($value)
135
129
return self ::$ instances [$ class ][$ value ];
136
130
}
137
131
138
- $ instance = new $ class ($ value );
139
- self ::$ instances [$ class ][$ value ] = $ instance ;
140
- return $ instance ;
132
+ // find the real value
133
+ $ constants = self ::detectConstants ($ class );
134
+ $ name = array_search ($ value , $ constants );
135
+ if ($ name === false ) {
136
+ throw new InvalidArgumentException ("Unknown value ' {$ value }' " );
137
+ }
138
+
139
+ return self ::$ instances [$ class ][$ value ] = new $ class ($ constants [$ name ]);
141
140
}
142
141
143
142
/**
@@ -150,12 +149,18 @@ final static public function get($value)
150
149
*/
151
150
final public static function getByName ($ name )
152
151
{
153
- $ classConst = ' static:: ' . $ name ;
154
- if (! defined ( $ classConst )) {
155
- $ class = get_called_class ();
156
- throw new InvalidArgumentException ($ class . ' :: ' . $ name . ' not defined ' );
152
+ $ class = get_called_class () ;
153
+ $ const = $ class . ' :: ' . $ name ;
154
+ if (! defined ( $ const )) {
155
+ throw new InvalidArgumentException ($ const . ' not defined ' );
157
156
}
158
- return static ::get (constant ($ classConst ));
157
+
158
+ $ value = constant ($ const );
159
+ if (isset (self ::$ instances [$ class ][$ value ])) {
160
+ return self ::$ instances [$ class ][$ value ];
161
+ }
162
+
163
+ return self ::$ instances [$ class ][$ value ] = new $ class ($ value );
159
164
}
160
165
161
166
/**
@@ -168,15 +173,23 @@ final public static function getByName($name)
168
173
*/
169
174
final public static function getByOrdinal ($ ordinal )
170
175
{
171
- $ constants = static ::getConstants ();
176
+ $ ordinal = (int ) $ ordinal ;
177
+ $ class = get_called_class ();
178
+ $ constants = self ::detectConstants ($ class );
172
179
$ item = array_slice ($ constants , $ ordinal , 1 , false );
173
180
if (!$ item ) {
174
181
throw new InvalidArgumentException (sprintf (
175
182
'Invalid ordinal number, must between 0 and %s ' ,
176
183
count ($ constants ) - 1
177
184
));
178
185
}
179
- return static ::get (current ($ item ));
186
+
187
+ $ value = current ($ item );
188
+ if (isset (self ::$ instances [$ class ][$ value ])) {
189
+ return self ::$ instances [$ class ][$ value ];
190
+ }
191
+
192
+ return self ::$ instances [$ class ][$ value ] = new $ class ($ value , $ ordinal );
180
193
}
181
194
182
195
/**
@@ -189,22 +202,8 @@ final public static function getByOrdinal($ordinal)
189
202
*/
190
203
final static public function clear ()
191
204
{
192
- $ class = get_called_class ();
193
-
194
- // clear instantiated enums
195
- foreach (self ::$ instances as $ instanceClass => $ enum ) {
196
- if (strcasecmp ($ class , $ instanceClass ) === 0 ) {
197
- unset(self ::$ instances [$ instanceClass ]);
198
- }
199
- }
200
-
201
- // clear constants buffer
202
- foreach (self ::$ constants as $ constantsClass => & $ constants ) {
203
- if (strcasecmp ($ class , $ constantsClass ) === 0 ) {
204
- unset(self ::$ constants [$ constantsClass ]);
205
- break ;
206
- }
207
- }
205
+ $ class = get_called_class ();
206
+ unset(self ::$ instances [$ class ], self ::$ constants [$ class ]);
208
207
}
209
208
210
209
/**
@@ -214,32 +213,41 @@ final static public function clear()
214
213
*/
215
214
final static public function getConstants ()
216
215
{
217
- $ class = get_called_class ();
218
- if (isset (self ::$ constants [$ class ])) {
219
- return self ::$ constants [$ class ];
220
- }
216
+ return self ::detectConstants (get_called_class ());
217
+ }
221
218
222
- $ reflection = new ReflectionClass ($ class );
223
- $ constants = $ reflection ->getConstants ();
219
+ /**
220
+ * Detect constants available by given class
221
+ * @param string $class
222
+ * @return void
223
+ * @throws LogicException On ambiguous constant values
224
+ */
225
+ static private function detectConstants ($ class )
226
+ {
227
+ if (!isset (self ::$ constants [$ class ])) {
228
+ $ reflection = new ReflectionClass ($ class );
229
+ $ constants = $ reflection ->getConstants ();
224
230
225
- // Constant values needs to be unique
226
- if (max (array_count_values ($ constants )) > 1 ) {
227
- $ ambiguous = array_map (function ($ v ) use ($ constants ) {
228
- return implode ('/ ' , array_keys ($ constants , $ v )) . '= ' . $ v ;
229
- }, array_unique (array_diff_assoc ($ constants , array_unique ($ constants ))));
230
- throw new LogicException (sprintf (
231
- 'All possible values needs to be unique. The following are ambiguous: %s ' ,
232
- implode (', ' , $ ambiguous )
233
- ));
234
- }
231
+ // Constant values needs to be unique
232
+ if (max (array_count_values ($ constants )) > 1 ) {
233
+ $ ambiguous = array_map (function ($ v ) use ($ constants ) {
234
+ return implode ('/ ' , array_keys ($ constants , $ v )) . '= ' . $ v ;
235
+ }, array_unique (array_diff_assoc ($ constants , array_unique ($ constants ))));
236
+ throw new LogicException (sprintf (
237
+ 'All possible values needs to be unique. The following are ambiguous: %s ' ,
238
+ implode (', ' , $ ambiguous )
239
+ ));
240
+ }
241
+
242
+ // This is required to make sure that constants of base classes will be the first
243
+ while (($ reflection = $ reflection ->getParentClass ()) && $ reflection ->name != 'MabeEnum\Enum ' ) {
244
+ $ constants = $ reflection ->getConstants () + $ constants ;
245
+ }
235
246
236
- // This is required to make sure that constants of base classes will be the first
237
- while ( ($ reflection = $ reflection ->getParentClass ()) ) {
238
- $ constants = $ reflection ->getConstants () + $ constants ;
247
+ self ::$ constants [$ class ] = $ constants ;
239
248
}
240
249
241
- self ::$ constants [$ class ] = $ constants ;
242
- return $ constants ;
250
+ return self ::$ constants [$ class ];
243
251
}
244
252
245
253
/**
0 commit comments