@@ -160,27 +160,55 @@ public static function loadFile($path)
160160 return self ::$ loadedClasses [$ path ];
161161 }
162162
163- $ classes = get_declared_classes ();
164- $ interfaces = get_declared_interfaces ();
165- $ traits = get_declared_traits ();
163+ $ classesBeforeLoad = [
164+ 'classes ' => get_declared_classes (),
165+ 'interfaces ' => get_declared_interfaces (),
166+ 'traits ' => get_declared_traits (),
167+ ];
166168
167169 include $ path ;
168170
169- $ className = null ;
170- $ newClasses = array_reverse (array_diff (get_declared_classes (), $ classes ));
171- // Since PHP 7.4 get_declared_classes() does not guarantee any order. That
172- // implies that parent classes aren't the first any more, rendering the
173- // array_reverse() technique futile for the loop & break code that follows.
174- // So, additionally, let's try to reduce the list of candidates by removing all
175- // the classes known to be "parents". That way, at the end, only the "main"
176- // class just included with remain.
171+ $ classesAfterLoad = [
172+ 'classes ' => get_declared_classes (),
173+ 'interfaces ' => get_declared_interfaces (),
174+ 'traits ' => get_declared_traits (),
175+ ];
176+
177+ $ className = self ::determineLoadedClass ($ classesBeforeLoad , $ classesAfterLoad );
178+
179+ self ::$ loadedClasses [$ path ] = $ className ;
180+ self ::$ loadedFiles [$ className ] = $ path ;
181+ return self ::$ loadedClasses [$ path ];
182+
183+ }//end loadFile()
184+
185+
186+ /**
187+ * Determine which class was loaded based on the before and after lists of loaded classes.
188+ *
189+ * @param array $classesBeforeLoad The classes/interfaces/traits before the file was included.
190+ * @param array $classesAfterLoad The classes/interfaces/traits after the file was included.
191+ *
192+ * @return string The fully qualified name of the class in the loaded file.
193+ */
194+ public static function determineLoadedClass ($ classesBeforeLoad , $ classesAfterLoad )
195+ {
196+ $ className = null ;
197+
198+ $ newClasses = array_diff ($ classesAfterLoad ['classes ' ], $ classesBeforeLoad ['classes ' ]);
199+
200+ // Since PHP 7.4 get_declared_classes() does not guarantee any order, making
201+ // it impossible to use order to determine which is the parent an which is the child.
202+ // Let's reduce the list of candidates by removing all the classes known to be "parents".
203+ // That way, at the end, only the "main" class just included will remain.
177204 $ newClasses = array_reduce (
178205 $ newClasses ,
179206 function ($ remaining , $ current ) {
180207 return array_diff ($ remaining , class_parents ($ current ));
181208 },
182209 $ newClasses
183210 );
211+
184212 foreach ($ newClasses as $ name ) {
185213 if (isset (self ::$ loadedFiles [$ name ]) === false ) {
186214 $ className = $ name ;
@@ -189,7 +217,7 @@ function ($remaining, $current) {
189217 }
190218
191219 if ($ className === null ) {
192- $ newClasses = array_reverse (array_diff (get_declared_interfaces () , $ interfaces ));
220+ $ newClasses = array_reverse (array_diff ($ classesAfterLoad [ ' interfaces ' ] , $ classesBeforeLoad [ ' interfaces ' ] ));
193221 foreach ($ newClasses as $ name ) {
194222 if (isset (self ::$ loadedFiles [$ name ]) === false ) {
195223 $ className = $ name ;
@@ -199,7 +227,7 @@ function ($remaining, $current) {
199227 }
200228
201229 if ($ className === null ) {
202- $ newClasses = array_reverse (array_diff (get_declared_traits () , $ traits ));
230+ $ newClasses = array_reverse (array_diff ($ classesAfterLoad [ ' traits ' ] , $ classesBeforeLoad [ ' traits ' ] ));
203231 foreach ($ newClasses as $ name ) {
204232 if (isset (self ::$ loadedFiles [$ name ]) === false ) {
205233 $ className = $ name ;
@@ -208,11 +236,9 @@ function ($remaining, $current) {
208236 }
209237 }
210238
211- self ::$ loadedClasses [$ path ] = $ className ;
212- self ::$ loadedFiles [$ className ] = $ path ;
213- return self ::$ loadedClasses [$ path ];
239+ return $ className ;
214240
215- }//end loadFile ()
241+ }//end determineLoadedClass ()
216242
217243
218244 /**
0 commit comments