Rev 861 | Rev 958 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 861 | Rev 874 | ||
---|---|---|---|
Line 40... | Line 40... | ||
40 | * @see https://www.php-fig.org/psr/psr-0/ |
40 | * @see https://www.php-fig.org/psr/psr-0/ |
41 | * @see https://www.php-fig.org/psr/psr-4/ |
41 | * @see https://www.php-fig.org/psr/psr-4/ |
42 | */ |
42 | */ |
43 | class ClassLoader |
43 | class ClassLoader |
44 | { |
44 | { |
45 | /** @var ?string */ |
- | |
46 | private $vendorDir; |
45 | private $vendorDir; |
47 | 46 | ||
48 | // PSR-4 |
47 | // PSR-4 |
49 | /** |
- | |
50 | * @var array[] |
- | |
51 | * @psalm-var array<string, array<string, int>> |
- | |
52 | */ |
- | |
53 | private $prefixLengthsPsr4 = array(); |
48 | private $prefixLengthsPsr4 = array(); |
54 | /** |
- | |
55 | * @var array[] |
- | |
56 | * @psalm-var array<string, array<int, string>> |
- | |
57 | */ |
- | |
58 | private $prefixDirsPsr4 = array(); |
49 | private $prefixDirsPsr4 = array(); |
59 | /** |
- | |
60 | * @var array[] |
- | |
61 | * @psalm-var array<string, string> |
- | |
62 | */ |
- | |
63 | private $fallbackDirsPsr4 = array(); |
50 | private $fallbackDirsPsr4 = array(); |
64 | 51 | ||
65 | // PSR-0 |
52 | // PSR-0 |
66 | /** |
- | |
67 | * @var array[] |
- | |
68 | * @psalm-var array<string, array<string, string[]>> |
- | |
69 | */ |
- | |
70 | private $prefixesPsr0 = array(); |
53 | private $prefixesPsr0 = array(); |
71 | /** |
- | |
72 | * @var array[] |
- | |
73 | * @psalm-var array<string, string> |
- | |
74 | */ |
- | |
75 | private $fallbackDirsPsr0 = array(); |
54 | private $fallbackDirsPsr0 = array(); |
76 | 55 | ||
77 | /** @var bool */ |
- | |
78 | private $useIncludePath = false; |
56 | private $useIncludePath = false; |
79 | - | ||
80 | /** |
- | |
81 | * @var string[] |
- | |
82 | * @psalm-var array<string, string> |
- | |
83 | */ |
- | |
84 | private $classMap = array(); |
57 | private $classMap = array(); |
85 | - | ||
86 | /** @var bool */ |
- | |
87 | private $classMapAuthoritative = false; |
58 | private $classMapAuthoritative = false; |
88 | - | ||
89 | /** |
- | |
90 | * @var bool[] |
- | |
91 | * @psalm-var array<string, bool> |
- | |
92 | */ |
- | |
93 | private $missingClasses = array(); |
59 | private $missingClasses = array(); |
94 | - | ||
95 | /** @var ?string */ |
- | |
96 | private $apcuPrefix; |
60 | private $apcuPrefix; |
97 | 61 | ||
98 | /** |
- | |
99 | * @var self[] |
- | |
100 | */ |
- | |
101 | private static $registeredLoaders = array(); |
62 | private static $registeredLoaders = array(); |
102 | 63 | ||
103 | /** |
- | |
104 | * @param ?string $vendorDir |
- | |
105 | */ |
- | |
106 | public function __construct($vendorDir = null) |
64 | public function __construct($vendorDir = null) |
107 | { |
65 | { |
108 | $this->vendorDir = $vendorDir; |
66 | $this->vendorDir = $vendorDir; |
109 | } |
67 | } |
110 | 68 | ||
111 | /** |
- | |
112 | * @return string[] |
- | |
113 | */ |
- | |
114 | public function getPrefixes() |
69 | public function getPrefixes() |
115 | { |
70 | { |
116 | if (!empty($this->prefixesPsr0)) { |
71 | if (!empty($this->prefixesPsr0)) { |
117 | return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); |
72 | return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); |
118 | } |
73 | } |
119 | 74 | ||
120 | return array(); |
75 | return array(); |
121 | } |
76 | } |
122 | 77 | ||
123 | /** |
- | |
124 | * @return array[] |
- | |
125 | * @psalm-return array<string, array<int, string>> |
- | |
126 | */ |
- | |
127 | public function getPrefixesPsr4() |
78 | public function getPrefixesPsr4() |
128 | { |
79 | { |
129 | return $this->prefixDirsPsr4; |
80 | return $this->prefixDirsPsr4; |
130 | } |
81 | } |
131 | 82 | ||
132 | /** |
- | |
133 | * @return array[] |
- | |
134 | * @psalm-return array<string, string> |
- | |
135 | */ |
- | |
136 | public function getFallbackDirs() |
83 | public function getFallbackDirs() |
137 | { |
84 | { |
138 | return $this->fallbackDirsPsr0; |
85 | return $this->fallbackDirsPsr0; |
139 | } |
86 | } |
140 | 87 | ||
141 | /** |
- | |
142 | * @return array[] |
- | |
143 | * @psalm-return array<string, string> |
- | |
144 | */ |
- | |
145 | public function getFallbackDirsPsr4() |
88 | public function getFallbackDirsPsr4() |
146 | { |
89 | { |
147 | return $this->fallbackDirsPsr4; |
90 | return $this->fallbackDirsPsr4; |
148 | } |
91 | } |
149 | 92 | ||
150 | /** |
- | |
151 | * @return string[] Array of classname => path |
- | |
152 | * @psalm-return array<string, string> |
- | |
153 | */ |
- | |
154 | public function getClassMap() |
93 | public function getClassMap() |
155 | { |
94 | { |
156 | return $this->classMap; |
95 | return $this->classMap; |
157 | } |
96 | } |
158 | 97 | ||
159 | /** |
98 | /** |
160 | * @param string[] $classMap Class to filename map |
99 | * @param array $classMap Class to filename map |
161 | * @psalm-param array<string, string> $classMap |
- | |
162 | * |
- | |
163 | * @return void |
- | |
164 | */ |
100 | */ |
165 | public function addClassMap(array $classMap) |
101 | public function addClassMap(array $classMap) |
166 | { |
102 | { |
167 | if ($this->classMap) { |
103 | if ($this->classMap) { |
168 | $this->classMap = array_merge($this->classMap, $classMap); |
104 | $this->classMap = array_merge($this->classMap, $classMap); |
Line 174... | Line 110... | ||
174 | /** |
110 | /** |
175 | * Registers a set of PSR-0 directories for a given prefix, either |
111 | * Registers a set of PSR-0 directories for a given prefix, either |
176 | * appending or prepending to the ones previously set for this prefix. |
112 | * appending or prepending to the ones previously set for this prefix. |
177 | * |
113 | * |
178 | * @param string $prefix The prefix |
114 | * @param string $prefix The prefix |
179 | * @param string[]|string $paths The PSR-0 root directories |
115 | * @param array|string $paths The PSR-0 root directories |
180 | * @param bool $prepend Whether to prepend the directories |
116 | * @param bool $prepend Whether to prepend the directories |
181 | * |
- | |
182 | * @return void |
- | |
183 | */ |
117 | */ |
184 | public function add($prefix, $paths, $prepend = false) |
118 | public function add($prefix, $paths, $prepend = false) |
185 | { |
119 | { |
186 | if (!$prefix) { |
120 | if (!$prefix) { |
187 | if ($prepend) { |
121 | if ($prepend) { |
Line 221... | Line 155... | ||
221 | /** |
155 | /** |
222 | * Registers a set of PSR-4 directories for a given namespace, either |
156 | * Registers a set of PSR-4 directories for a given namespace, either |
223 | * appending or prepending to the ones previously set for this namespace. |
157 | * appending or prepending to the ones previously set for this namespace. |
224 | * |
158 | * |
225 | * @param string $prefix The prefix/namespace, with trailing '\\' |
159 | * @param string $prefix The prefix/namespace, with trailing '\\' |
226 | * @param string[]|string $paths The PSR-4 base directories |
160 | * @param array|string $paths The PSR-4 base directories |
227 | * @param bool $prepend Whether to prepend the directories |
161 | * @param bool $prepend Whether to prepend the directories |
228 | * |
162 | * |
229 | * @throws \InvalidArgumentException |
163 | * @throws \InvalidArgumentException |
230 | * |
- | |
231 | * @return void |
- | |
232 | */ |
164 | */ |
233 | public function addPsr4($prefix, $paths, $prepend = false) |
165 | public function addPsr4($prefix, $paths, $prepend = false) |
234 | { |
166 | { |
235 | if (!$prefix) { |
167 | if (!$prefix) { |
236 | // Register directories for the root namespace. |
168 | // Register directories for the root namespace. |
Line 271... | Line 203... | ||
271 | /** |
203 | /** |
272 | * Registers a set of PSR-0 directories for a given prefix, |
204 | * Registers a set of PSR-0 directories for a given prefix, |
273 | * replacing any others previously set for this prefix. |
205 | * replacing any others previously set for this prefix. |
274 | * |
206 | * |
275 | * @param string $prefix The prefix |
207 | * @param string $prefix The prefix |
276 | * @param string[]|string $paths The PSR-0 base directories |
208 | * @param array|string $paths The PSR-0 base directories |
277 | * |
- | |
278 | * @return void |
- | |
279 | */ |
209 | */ |
280 | public function set($prefix, $paths) |
210 | public function set($prefix, $paths) |
281 | { |
211 | { |
282 | if (!$prefix) { |
212 | if (!$prefix) { |
283 | $this->fallbackDirsPsr0 = (array) $paths; |
213 | $this->fallbackDirsPsr0 = (array) $paths; |
Line 289... | Line 219... | ||
289 | /** |
219 | /** |
290 | * Registers a set of PSR-4 directories for a given namespace, |
220 | * Registers a set of PSR-4 directories for a given namespace, |
291 | * replacing any others previously set for this namespace. |
221 | * replacing any others previously set for this namespace. |
292 | * |
222 | * |
293 | * @param string $prefix The prefix/namespace, with trailing '\\' |
223 | * @param string $prefix The prefix/namespace, with trailing '\\' |
294 | * @param string[]|string $paths The PSR-4 base directories |
224 | * @param array|string $paths The PSR-4 base directories |
295 | * |
225 | * |
296 | * @throws \InvalidArgumentException |
226 | * @throws \InvalidArgumentException |
297 | * |
- | |
298 | * @return void |
- | |
299 | */ |
227 | */ |
300 | public function setPsr4($prefix, $paths) |
228 | public function setPsr4($prefix, $paths) |
301 | { |
229 | { |
302 | if (!$prefix) { |
230 | if (!$prefix) { |
303 | $this->fallbackDirsPsr4 = (array) $paths; |
231 | $this->fallbackDirsPsr4 = (array) $paths; |
Line 313... | Line 241... | ||
313 | 241 | ||
314 | /** |
242 | /** |
315 | * Turns on searching the include path for class files. |
243 | * Turns on searching the include path for class files. |
316 | * |
244 | * |
317 | * @param bool $useIncludePath |
245 | * @param bool $useIncludePath |
318 | * |
- | |
319 | * @return void |
- | |
320 | */ |
246 | */ |
321 | public function setUseIncludePath($useIncludePath) |
247 | public function setUseIncludePath($useIncludePath) |
322 | { |
248 | { |
323 | $this->useIncludePath = $useIncludePath; |
249 | $this->useIncludePath = $useIncludePath; |
324 | } |
250 | } |
Line 337... | Line 263... | ||
337 | /** |
263 | /** |
338 | * Turns off searching the prefix and fallback directories for classes |
264 | * Turns off searching the prefix and fallback directories for classes |
339 | * that have not been registered with the class map. |
265 | * that have not been registered with the class map. |
340 | * |
266 | * |
341 | * @param bool $classMapAuthoritative |
267 | * @param bool $classMapAuthoritative |
342 | * |
- | |
343 | * @return void |
- | |
344 | */ |
268 | */ |
345 | public function setClassMapAuthoritative($classMapAuthoritative) |
269 | public function setClassMapAuthoritative($classMapAuthoritative) |
346 | { |
270 | { |
347 | $this->classMapAuthoritative = $classMapAuthoritative; |
271 | $this->classMapAuthoritative = $classMapAuthoritative; |
348 | } |
272 | } |
Line 359... | Line 283... | ||
359 | 283 | ||
360 | /** |
284 | /** |
361 | * APCu prefix to use to cache found/not-found classes, if the extension is enabled. |
285 | * APCu prefix to use to cache found/not-found classes, if the extension is enabled. |
362 | * |
286 | * |
363 | * @param string|null $apcuPrefix |
287 | * @param string|null $apcuPrefix |
364 | * |
- | |
365 | * @return void |
- | |
366 | */ |
288 | */ |
367 | public function setApcuPrefix($apcuPrefix) |
289 | public function setApcuPrefix($apcuPrefix) |
368 | { |
290 | { |
369 | $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; |
291 | $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; |
370 | } |
292 | } |
Line 381... | Line 303... | ||
381 | 303 | ||
382 | /** |
304 | /** |
383 | * Registers this instance as an autoloader. |
305 | * Registers this instance as an autoloader. |
384 | * |
306 | * |
385 | * @param bool $prepend Whether to prepend the autoloader or not |
307 | * @param bool $prepend Whether to prepend the autoloader or not |
386 | * |
- | |
387 | * @return void |
- | |
388 | */ |
308 | */ |
389 | public function register($prepend = false) |
309 | public function register($prepend = false) |
390 | { |
310 | { |
391 | spl_autoload_register(array($this, 'loadClass'), true, $prepend); |
311 | spl_autoload_register(array($this, 'loadClass'), true, $prepend); |
392 | 312 | ||
Line 402... | Line 322... | ||
402 | } |
322 | } |
403 | } |
323 | } |
404 | 324 | ||
405 | /** |
325 | /** |
406 | * Unregisters this instance as an autoloader. |
326 | * Unregisters this instance as an autoloader. |
407 | * |
- | |
408 | * @return void |
- | |
409 | */ |
327 | */ |
410 | public function unregister() |
328 | public function unregister() |
411 | { |
329 | { |
412 | spl_autoload_unregister(array($this, 'loadClass')); |
330 | spl_autoload_unregister(array($this, 'loadClass')); |
413 | 331 | ||
Line 418... | Line 336... | ||
418 | 336 | ||
419 | /** |
337 | /** |
420 | * Loads the given class or interface. |
338 | * Loads the given class or interface. |
421 | * |
339 | * |
422 | * @param string $class The name of the class |
340 | * @param string $class The name of the class |
423 | * @return true|null True if loaded, null otherwise |
341 | * @return bool|null True if loaded, null otherwise |
424 | */ |
342 | */ |
425 | public function loadClass($class) |
343 | public function loadClass($class) |
426 | { |
344 | { |
427 | if ($file = $this->findFile($class)) { |
345 | if ($file = $this->findFile($class)) { |
428 | includeFile($file); |
346 | includeFile($file); |
429 | 347 | ||
430 | return true; |
348 | return true; |
431 | } |
349 | } |
432 | - | ||
433 | return null; |
- | |
434 | } |
350 | } |
435 | 351 | ||
436 | /** |
352 | /** |
437 | * Finds the path to the file where the class is defined. |
353 | * Finds the path to the file where the class is defined. |
438 | * |
354 | * |
Line 483... | Line 399... | ||
483 | public static function getRegisteredLoaders() |
399 | public static function getRegisteredLoaders() |
484 | { |
400 | { |
485 | return self::$registeredLoaders; |
401 | return self::$registeredLoaders; |
486 | } |
402 | } |
487 | 403 | ||
488 | /** |
- | |
489 | * @param string $class |
- | |
490 | * @param string $ext |
- | |
491 | * @return string|false |
- | |
492 | */ |
- | |
493 | private function findFileWithExtension($class, $ext) |
404 | private function findFileWithExtension($class, $ext) |
494 | { |
405 | { |
495 | // PSR-4 lookup |
406 | // PSR-4 lookup |
496 | $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; |
407 | $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; |
497 | 408 | ||
Line 559... | Line 470... | ||
559 | 470 | ||
560 | /** |
471 | /** |
561 | * Scope isolated include. |
472 | * Scope isolated include. |
562 | * |
473 | * |
563 | * Prevents access to $this/self from included files. |
474 | * Prevents access to $this/self from included files. |
564 | * |
- | |
565 | * @param string $file |
- | |
566 | * @return void |
- | |
567 | * @private |
- | |
568 | */ |
475 | */ |
569 | function includeFile($file) |
476 | function includeFile($file) |
570 | { |
477 | { |
571 | include $file; |
478 | include $file; |
572 | } |
479 | } |