Skip to content

Commit 606a9d1

Browse files
committed
check included files for defined classes before include
including a file that re-redefines leads to a fatal error, making phpcs fail hard. including files from a rule-set while these files may have already been included (likely by auto-loading and could then be seen as a race- condition) now checks if it has been already included and if so, searches all loaded classes for the class-name and if found, verifies the class is from that file. this effectively prevents the fatal error and works for classes / files with a PSR-4 naming scheme.
1 parent d2574b9 commit 606a9d1

File tree

1 file changed

+44
-1
lines changed

1 file changed

+44
-1
lines changed

Diff for: autoload.php

+44-1
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,38 @@ public static function load($class)
140140
}//end load()
141141

142142

143+
/**
144+
* Determine which class was loaded from path
145+
*
146+
* @param array $classesBeforeLoad The classes/interfaces/traits before the file was included.
147+
* @param string $path The path that already has been included.
148+
*
149+
* @return string The fully qualified name of the class in the loaded file.
150+
*/
151+
private static function determinePathClass(
152+
array $classesBeforeLoad, $path
153+
) {
154+
$alreadyIncluded = in_array($path, get_included_files(), true);
155+
if ($alreadyIncluded === false) {
156+
return null;
157+
}
158+
159+
$name = pathinfo($path, PATHINFO_FILENAME);
160+
$declared = preg_grep(
161+
'(\\\\'.preg_quote($name).'$)',
162+
$classesBeforeLoad['classes']
163+
);
164+
foreach ($declared as $className) {
165+
$reflection = new \ReflectionClass($className);
166+
$classFileName = $reflection->getFileName();
167+
if ($classFileName === $path) {
168+
return $className;
169+
}
170+
}
171+
172+
}//end determinePathClass()
173+
174+
143175
/**
144176
* Includes a file and tracks what class or interface was loaded as a result.
145177
*
@@ -166,6 +198,12 @@ public static function loadFile($path)
166198
'traits' => get_declared_traits(),
167199
];
168200

201+
$className = self::determinePathClass($classesBeforeLoad, $path);
202+
203+
if ($className !== null) {
204+
goto determined_className;
205+
}
206+
169207
include $path;
170208

171209
$classesAfterLoad = [
@@ -174,7 +212,12 @@ public static function loadFile($path)
174212
'traits' => get_declared_traits(),
175213
];
176214

177-
$className = self::determineLoadedClass($classesBeforeLoad, $classesAfterLoad);
215+
$className = self::determineLoadedClass(
216+
$classesBeforeLoad,
217+
$classesAfterLoad
218+
);
219+
220+
determined_className:
178221

179222
self::$loadedClasses[$path] = $className;
180223
self::$loadedFiles[$className] = $path;

0 commit comments

Comments
 (0)