PluginProbe
CSS & JavaScript Toolbox / 11.5
CSS & JavaScript Toolbox v11.5
trunk 0.3 0.8 10 10.1 11 11.2 11.3 11.4 11.5 11.6 11.7 11.8 11.9 11.9.1 12 12.0 12.0.1 12.0.3 12.0.4 12.0.5 12.0.6 12.0.7 6.0 6.0.11 All 60 releases
← All changes | vendor/composer/ClassLoader.php +74 -16 1011.5 View file →
@@ -12,12 +12,10 @@
12 12
13 13 namespace Composer\Autoload;
14 14
15 15 /**
16 - * ClassLoader implements a PSR-0 class loader
16 + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
17 17 *
18 - * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
19 - *
20 18 * $loader = new \Composer\Autoload\ClassLoader();
21 19 *
22 20 * // register classes with namespaces
23 21 * $loader->add('Symfony\Component', __DIR__.'/component');
@@ -38,8 +36,10 @@
38 36 * This class is loosely based on the Symfony UniversalClassLoader.
39 37 *
40 38 * @author Fabien Potencier <fabien@symfony.com>
41 39 * @author Jordi Boggiano <j.boggiano@seld.be>
40 + * @see http://www.php-fig.org/psr/psr-0/
41 + * @see http://www.php-fig.org/psr/psr-4/
42 42 */
43 43 class ClassLoader
44 44 {
45 45 // PSR-4
@@ -52,8 +52,11 @@
52 52 private $fallbackDirsPsr0 = array();
53 53
54 54 private $useIncludePath = false;
55 55 private $classMap = array();
56 + private $classMapAuthoritative = false;
57 + private $missingClasses = array();
58 + private $apcuPrefix;
56 59
57 60 public function getPrefixes()
58 61 {
59 62 if (!empty($this->prefixesPsr0)) {
@@ -144,9 +147,9 @@
144 147 * Registers a set of PSR-4 directories for a given namespace, either
145 148 * appending or prepending to the ones previously set for this namespace.
146 149 *
147 150 * @param string $prefix The prefix/namespace, with trailing '\\'
148 - * @param array|string $paths The PSR-0 base directories
151 + * @param array|string $paths The PSR-4 base directories
149 152 * @param bool $prepend Whether to prepend the directories
150 153 *
151 154 * @throws \InvalidArgumentException
152 155 */
@@ -248,8 +251,49 @@
248 251 return $this->useIncludePath;
249 252 }
250 253
251 254 /**
255 + * Turns off searching the prefix and fallback directories for classes
256 + * that have not been registered with the class map.
257 + *
258 + * @param bool $classMapAuthoritative
259 + */
260 + public function setClassMapAuthoritative($classMapAuthoritative)
261 + {
262 + $this->classMapAuthoritative = $classMapAuthoritative;
263 + }
264 +
265 + /**
266 + * Should class lookup fail if not found in the current class map?
267 + *
268 + * @return bool
269 + */
270 + public function isClassMapAuthoritative()
271 + {
272 + return $this->classMapAuthoritative;
273 + }
274 +
275 + /**
276 + * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
277 + *
278 + * @param string|null $apcuPrefix
279 + */
280 + public function setApcuPrefix($apcuPrefix)
281 + {
282 + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
283 + }
284 +
285 + /**
286 + * The APCu prefix in use, or null if APCu caching is not enabled.
287 + *
288 + * @return string|null
289 + */
290 + public function getApcuPrefix()
291 + {
292 + return $this->apcuPrefix;
293 + }
294 +
295 + /**
252 296 * Registers this instance as an autoloader.
253 297 *
254 298 * @param bool $prepend Whether to prepend the autoloader or not
255 299 */
@@ -289,28 +333,36 @@
289 333 * @return string|false The path if found, false otherwise
290 334 */
291 335 public function findFile($class)
292 336 {
293 - // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
294 - if ('\\' == $class[0]) {
295 - $class = substr($class, 1);
296 - }
297 -
298 337 // class map lookup
299 338 if (isset($this->classMap[$class])) {
300 339 return $this->classMap[$class];
301 340 }
341 + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
342 + return false;
343 + }
344 + if (null !== $this->apcuPrefix) {
345 + $file = apcu_fetch($this->apcuPrefix.$class, $hit);
346 + if ($hit) {
347 + return $file;
348 + }
349 + }
302 350
303 351 $file = $this->findFileWithExtension($class, '.php');
304 352
305 353 // Search for Hack files if we are running on HHVM
306 - if ($file === null && defined('HHVM_VERSION')) {
354 + if (false === $file && defined('HHVM_VERSION')) {
307 355 $file = $this->findFileWithExtension($class, '.hh');
308 356 }
309 357
310 - if ($file === null) {
358 + if (null !== $this->apcuPrefix) {
359 + apcu_add($this->apcuPrefix.$class, $file);
360 + }
361 +
362 + if (false === $file) {
311 363 // Remember that this class does not exist.
312 - return $this->classMap[$class] = false;
364 + $this->missingClasses[$class] = true;
313 365 }
314 366
315 367 return $file;
316 368 }
@@ -321,12 +373,16 @@
321 373 $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
322 374
323 375 $first = $class[0];
324 376 if (isset($this->prefixLengthsPsr4[$first])) {
325 - foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
326 - if (0 === strpos($class, $prefix)) {
327 - foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
328 - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
377 + $subPath = $class;
378 + while (false !== $lastPos = strrpos($subPath, '\\')) {
379 + $subPath = substr($subPath, 0, $lastPos);
380 + $search = $subPath . '\\';
381 + if (isset($this->prefixDirsPsr4[$search])) {
382 + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
383 + foreach ($this->prefixDirsPsr4[$search] as $dir) {
384 + if (file_exists($file = $dir . $pathEnd)) {
329 385 return $file;
330 386 }
331 387 }
332 388 }
@@ -372,8 +428,10 @@
372 428 // PSR-0 include paths.
373 429 if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
374 430 return $file;
375 431 }
432 +
433 + return false;
376 434 }
377 435 }
378 436
379 437 /**