1*37748cd8SNickeau<?php 2*37748cd8SNickeau 3*37748cd8SNickeau/* 4*37748cd8SNickeau * This file is part of Composer. 5*37748cd8SNickeau * 6*37748cd8SNickeau * (c) Nils Adermann <naderman@naderman.de> 7*37748cd8SNickeau * Jordi Boggiano <j.boggiano@seld.be> 8*37748cd8SNickeau * 9*37748cd8SNickeau * For the full copyright and license information, please view the LICENSE 10*37748cd8SNickeau * file that was distributed with this source code. 11*37748cd8SNickeau */ 12*37748cd8SNickeau 13*37748cd8SNickeaunamespace Composer\Autoload; 14*37748cd8SNickeau 15*37748cd8SNickeau/** 16*37748cd8SNickeau * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. 17*37748cd8SNickeau * 18*37748cd8SNickeau * $loader = new \Composer\Autoload\ClassLoader(); 19*37748cd8SNickeau * 20*37748cd8SNickeau * // register classes with namespaces 21*37748cd8SNickeau * $loader->add('Symfony\Component', __DIR__.'/component'); 22*37748cd8SNickeau * $loader->add('Symfony', __DIR__.'/framework'); 23*37748cd8SNickeau * 24*37748cd8SNickeau * // activate the autoloader 25*37748cd8SNickeau * $loader->register(); 26*37748cd8SNickeau * 27*37748cd8SNickeau * // to enable searching the include path (eg. for PEAR packages) 28*37748cd8SNickeau * $loader->setUseIncludePath(true); 29*37748cd8SNickeau * 30*37748cd8SNickeau * In this example, if you try to use a class in the Symfony\Component 31*37748cd8SNickeau * namespace or one of its children (Symfony\Component\Console for instance), 32*37748cd8SNickeau * the autoloader will first look for the class under the component/ 33*37748cd8SNickeau * directory, and it will then fallback to the framework/ directory if not 34*37748cd8SNickeau * found before giving up. 35*37748cd8SNickeau * 36*37748cd8SNickeau * This class is loosely based on the Symfony UniversalClassLoader. 37*37748cd8SNickeau * 38*37748cd8SNickeau * @author Fabien Potencier <fabien@symfony.com> 39*37748cd8SNickeau * @author Jordi Boggiano <j.boggiano@seld.be> 40*37748cd8SNickeau * @see https://www.php-fig.org/psr/psr-0/ 41*37748cd8SNickeau * @see https://www.php-fig.org/psr/psr-4/ 42*37748cd8SNickeau */ 43*37748cd8SNickeauclass ClassLoader 44*37748cd8SNickeau{ 45*37748cd8SNickeau private $vendorDir; 46*37748cd8SNickeau 47*37748cd8SNickeau // PSR-4 48*37748cd8SNickeau private $prefixLengthsPsr4 = array(); 49*37748cd8SNickeau private $prefixDirsPsr4 = array(); 50*37748cd8SNickeau private $fallbackDirsPsr4 = array(); 51*37748cd8SNickeau 52*37748cd8SNickeau // PSR-0 53*37748cd8SNickeau private $prefixesPsr0 = array(); 54*37748cd8SNickeau private $fallbackDirsPsr0 = array(); 55*37748cd8SNickeau 56*37748cd8SNickeau private $useIncludePath = false; 57*37748cd8SNickeau private $classMap = array(); 58*37748cd8SNickeau private $classMapAuthoritative = false; 59*37748cd8SNickeau private $missingClasses = array(); 60*37748cd8SNickeau private $apcuPrefix; 61*37748cd8SNickeau 62*37748cd8SNickeau private static $registeredLoaders = array(); 63*37748cd8SNickeau 64*37748cd8SNickeau public function __construct($vendorDir = null) 65*37748cd8SNickeau { 66*37748cd8SNickeau $this->vendorDir = $vendorDir; 67*37748cd8SNickeau } 68*37748cd8SNickeau 69*37748cd8SNickeau public function getPrefixes() 70*37748cd8SNickeau { 71*37748cd8SNickeau if (!empty($this->prefixesPsr0)) { 72*37748cd8SNickeau return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); 73*37748cd8SNickeau } 74*37748cd8SNickeau 75*37748cd8SNickeau return array(); 76*37748cd8SNickeau } 77*37748cd8SNickeau 78*37748cd8SNickeau public function getPrefixesPsr4() 79*37748cd8SNickeau { 80*37748cd8SNickeau return $this->prefixDirsPsr4; 81*37748cd8SNickeau } 82*37748cd8SNickeau 83*37748cd8SNickeau public function getFallbackDirs() 84*37748cd8SNickeau { 85*37748cd8SNickeau return $this->fallbackDirsPsr0; 86*37748cd8SNickeau } 87*37748cd8SNickeau 88*37748cd8SNickeau public function getFallbackDirsPsr4() 89*37748cd8SNickeau { 90*37748cd8SNickeau return $this->fallbackDirsPsr4; 91*37748cd8SNickeau } 92*37748cd8SNickeau 93*37748cd8SNickeau public function getClassMap() 94*37748cd8SNickeau { 95*37748cd8SNickeau return $this->classMap; 96*37748cd8SNickeau } 97*37748cd8SNickeau 98*37748cd8SNickeau /** 99*37748cd8SNickeau * @param array $classMap Class to filename map 100*37748cd8SNickeau */ 101*37748cd8SNickeau public function addClassMap(array $classMap) 102*37748cd8SNickeau { 103*37748cd8SNickeau if ($this->classMap) { 104*37748cd8SNickeau $this->classMap = array_merge($this->classMap, $classMap); 105*37748cd8SNickeau } else { 106*37748cd8SNickeau $this->classMap = $classMap; 107*37748cd8SNickeau } 108*37748cd8SNickeau } 109*37748cd8SNickeau 110*37748cd8SNickeau /** 111*37748cd8SNickeau * Registers a set of PSR-0 directories for a given prefix, either 112*37748cd8SNickeau * appending or prepending to the ones previously set for this prefix. 113*37748cd8SNickeau * 114*37748cd8SNickeau * @param string $prefix The prefix 115*37748cd8SNickeau * @param array|string $paths The PSR-0 root directories 116*37748cd8SNickeau * @param bool $prepend Whether to prepend the directories 117*37748cd8SNickeau */ 118*37748cd8SNickeau public function add($prefix, $paths, $prepend = false) 119*37748cd8SNickeau { 120*37748cd8SNickeau if (!$prefix) { 121*37748cd8SNickeau if ($prepend) { 122*37748cd8SNickeau $this->fallbackDirsPsr0 = array_merge( 123*37748cd8SNickeau (array) $paths, 124*37748cd8SNickeau $this->fallbackDirsPsr0 125*37748cd8SNickeau ); 126*37748cd8SNickeau } else { 127*37748cd8SNickeau $this->fallbackDirsPsr0 = array_merge( 128*37748cd8SNickeau $this->fallbackDirsPsr0, 129*37748cd8SNickeau (array) $paths 130*37748cd8SNickeau ); 131*37748cd8SNickeau } 132*37748cd8SNickeau 133*37748cd8SNickeau return; 134*37748cd8SNickeau } 135*37748cd8SNickeau 136*37748cd8SNickeau $first = $prefix[0]; 137*37748cd8SNickeau if (!isset($this->prefixesPsr0[$first][$prefix])) { 138*37748cd8SNickeau $this->prefixesPsr0[$first][$prefix] = (array) $paths; 139*37748cd8SNickeau 140*37748cd8SNickeau return; 141*37748cd8SNickeau } 142*37748cd8SNickeau if ($prepend) { 143*37748cd8SNickeau $this->prefixesPsr0[$first][$prefix] = array_merge( 144*37748cd8SNickeau (array) $paths, 145*37748cd8SNickeau $this->prefixesPsr0[$first][$prefix] 146*37748cd8SNickeau ); 147*37748cd8SNickeau } else { 148*37748cd8SNickeau $this->prefixesPsr0[$first][$prefix] = array_merge( 149*37748cd8SNickeau $this->prefixesPsr0[$first][$prefix], 150*37748cd8SNickeau (array) $paths 151*37748cd8SNickeau ); 152*37748cd8SNickeau } 153*37748cd8SNickeau } 154*37748cd8SNickeau 155*37748cd8SNickeau /** 156*37748cd8SNickeau * Registers a set of PSR-4 directories for a given namespace, either 157*37748cd8SNickeau * appending or prepending to the ones previously set for this namespace. 158*37748cd8SNickeau * 159*37748cd8SNickeau * @param string $prefix The prefix/namespace, with trailing '\\' 160*37748cd8SNickeau * @param array|string $paths The PSR-4 base directories 161*37748cd8SNickeau * @param bool $prepend Whether to prepend the directories 162*37748cd8SNickeau * 163*37748cd8SNickeau * @throws \InvalidArgumentException 164*37748cd8SNickeau */ 165*37748cd8SNickeau public function addPsr4($prefix, $paths, $prepend = false) 166*37748cd8SNickeau { 167*37748cd8SNickeau if (!$prefix) { 168*37748cd8SNickeau // Register directories for the root namespace. 169*37748cd8SNickeau if ($prepend) { 170*37748cd8SNickeau $this->fallbackDirsPsr4 = array_merge( 171*37748cd8SNickeau (array) $paths, 172*37748cd8SNickeau $this->fallbackDirsPsr4 173*37748cd8SNickeau ); 174*37748cd8SNickeau } else { 175*37748cd8SNickeau $this->fallbackDirsPsr4 = array_merge( 176*37748cd8SNickeau $this->fallbackDirsPsr4, 177*37748cd8SNickeau (array) $paths 178*37748cd8SNickeau ); 179*37748cd8SNickeau } 180*37748cd8SNickeau } elseif (!isset($this->prefixDirsPsr4[$prefix])) { 181*37748cd8SNickeau // Register directories for a new namespace. 182*37748cd8SNickeau $length = strlen($prefix); 183*37748cd8SNickeau if ('\\' !== $prefix[$length - 1]) { 184*37748cd8SNickeau throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); 185*37748cd8SNickeau } 186*37748cd8SNickeau $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; 187*37748cd8SNickeau $this->prefixDirsPsr4[$prefix] = (array) $paths; 188*37748cd8SNickeau } elseif ($prepend) { 189*37748cd8SNickeau // Prepend directories for an already registered namespace. 190*37748cd8SNickeau $this->prefixDirsPsr4[$prefix] = array_merge( 191*37748cd8SNickeau (array) $paths, 192*37748cd8SNickeau $this->prefixDirsPsr4[$prefix] 193*37748cd8SNickeau ); 194*37748cd8SNickeau } else { 195*37748cd8SNickeau // Append directories for an already registered namespace. 196*37748cd8SNickeau $this->prefixDirsPsr4[$prefix] = array_merge( 197*37748cd8SNickeau $this->prefixDirsPsr4[$prefix], 198*37748cd8SNickeau (array) $paths 199*37748cd8SNickeau ); 200*37748cd8SNickeau } 201*37748cd8SNickeau } 202*37748cd8SNickeau 203*37748cd8SNickeau /** 204*37748cd8SNickeau * Registers a set of PSR-0 directories for a given prefix, 205*37748cd8SNickeau * replacing any others previously set for this prefix. 206*37748cd8SNickeau * 207*37748cd8SNickeau * @param string $prefix The prefix 208*37748cd8SNickeau * @param array|string $paths The PSR-0 base directories 209*37748cd8SNickeau */ 210*37748cd8SNickeau public function set($prefix, $paths) 211*37748cd8SNickeau { 212*37748cd8SNickeau if (!$prefix) { 213*37748cd8SNickeau $this->fallbackDirsPsr0 = (array) $paths; 214*37748cd8SNickeau } else { 215*37748cd8SNickeau $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; 216*37748cd8SNickeau } 217*37748cd8SNickeau } 218*37748cd8SNickeau 219*37748cd8SNickeau /** 220*37748cd8SNickeau * Registers a set of PSR-4 directories for a given namespace, 221*37748cd8SNickeau * replacing any others previously set for this namespace. 222*37748cd8SNickeau * 223*37748cd8SNickeau * @param string $prefix The prefix/namespace, with trailing '\\' 224*37748cd8SNickeau * @param array|string $paths The PSR-4 base directories 225*37748cd8SNickeau * 226*37748cd8SNickeau * @throws \InvalidArgumentException 227*37748cd8SNickeau */ 228*37748cd8SNickeau public function setPsr4($prefix, $paths) 229*37748cd8SNickeau { 230*37748cd8SNickeau if (!$prefix) { 231*37748cd8SNickeau $this->fallbackDirsPsr4 = (array) $paths; 232*37748cd8SNickeau } else { 233*37748cd8SNickeau $length = strlen($prefix); 234*37748cd8SNickeau if ('\\' !== $prefix[$length - 1]) { 235*37748cd8SNickeau throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); 236*37748cd8SNickeau } 237*37748cd8SNickeau $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; 238*37748cd8SNickeau $this->prefixDirsPsr4[$prefix] = (array) $paths; 239*37748cd8SNickeau } 240*37748cd8SNickeau } 241*37748cd8SNickeau 242*37748cd8SNickeau /** 243*37748cd8SNickeau * Turns on searching the include path for class files. 244*37748cd8SNickeau * 245*37748cd8SNickeau * @param bool $useIncludePath 246*37748cd8SNickeau */ 247*37748cd8SNickeau public function setUseIncludePath($useIncludePath) 248*37748cd8SNickeau { 249*37748cd8SNickeau $this->useIncludePath = $useIncludePath; 250*37748cd8SNickeau } 251*37748cd8SNickeau 252*37748cd8SNickeau /** 253*37748cd8SNickeau * Can be used to check if the autoloader uses the include path to check 254*37748cd8SNickeau * for classes. 255*37748cd8SNickeau * 256*37748cd8SNickeau * @return bool 257*37748cd8SNickeau */ 258*37748cd8SNickeau public function getUseIncludePath() 259*37748cd8SNickeau { 260*37748cd8SNickeau return $this->useIncludePath; 261*37748cd8SNickeau } 262*37748cd8SNickeau 263*37748cd8SNickeau /** 264*37748cd8SNickeau * Turns off searching the prefix and fallback directories for classes 265*37748cd8SNickeau * that have not been registered with the class map. 266*37748cd8SNickeau * 267*37748cd8SNickeau * @param bool $classMapAuthoritative 268*37748cd8SNickeau */ 269*37748cd8SNickeau public function setClassMapAuthoritative($classMapAuthoritative) 270*37748cd8SNickeau { 271*37748cd8SNickeau $this->classMapAuthoritative = $classMapAuthoritative; 272*37748cd8SNickeau } 273*37748cd8SNickeau 274*37748cd8SNickeau /** 275*37748cd8SNickeau * Should class lookup fail if not found in the current class map? 276*37748cd8SNickeau * 277*37748cd8SNickeau * @return bool 278*37748cd8SNickeau */ 279*37748cd8SNickeau public function isClassMapAuthoritative() 280*37748cd8SNickeau { 281*37748cd8SNickeau return $this->classMapAuthoritative; 282*37748cd8SNickeau } 283*37748cd8SNickeau 284*37748cd8SNickeau /** 285*37748cd8SNickeau * APCu prefix to use to cache found/not-found classes, if the extension is enabled. 286*37748cd8SNickeau * 287*37748cd8SNickeau * @param string|null $apcuPrefix 288*37748cd8SNickeau */ 289*37748cd8SNickeau public function setApcuPrefix($apcuPrefix) 290*37748cd8SNickeau { 291*37748cd8SNickeau $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; 292*37748cd8SNickeau } 293*37748cd8SNickeau 294*37748cd8SNickeau /** 295*37748cd8SNickeau * The APCu prefix in use, or null if APCu caching is not enabled. 296*37748cd8SNickeau * 297*37748cd8SNickeau * @return string|null 298*37748cd8SNickeau */ 299*37748cd8SNickeau public function getApcuPrefix() 300*37748cd8SNickeau { 301*37748cd8SNickeau return $this->apcuPrefix; 302*37748cd8SNickeau } 303*37748cd8SNickeau 304*37748cd8SNickeau /** 305*37748cd8SNickeau * Registers this instance as an autoloader. 306*37748cd8SNickeau * 307*37748cd8SNickeau * @param bool $prepend Whether to prepend the autoloader or not 308*37748cd8SNickeau */ 309*37748cd8SNickeau public function register($prepend = false) 310*37748cd8SNickeau { 311*37748cd8SNickeau spl_autoload_register(array($this, 'loadClass'), true, $prepend); 312*37748cd8SNickeau 313*37748cd8SNickeau if (null === $this->vendorDir) { 314*37748cd8SNickeau return; 315*37748cd8SNickeau } 316*37748cd8SNickeau 317*37748cd8SNickeau if ($prepend) { 318*37748cd8SNickeau self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; 319*37748cd8SNickeau } else { 320*37748cd8SNickeau unset(self::$registeredLoaders[$this->vendorDir]); 321*37748cd8SNickeau self::$registeredLoaders[$this->vendorDir] = $this; 322*37748cd8SNickeau } 323*37748cd8SNickeau } 324*37748cd8SNickeau 325*37748cd8SNickeau /** 326*37748cd8SNickeau * Unregisters this instance as an autoloader. 327*37748cd8SNickeau */ 328*37748cd8SNickeau public function unregister() 329*37748cd8SNickeau { 330*37748cd8SNickeau spl_autoload_unregister(array($this, 'loadClass')); 331*37748cd8SNickeau 332*37748cd8SNickeau if (null !== $this->vendorDir) { 333*37748cd8SNickeau unset(self::$registeredLoaders[$this->vendorDir]); 334*37748cd8SNickeau } 335*37748cd8SNickeau } 336*37748cd8SNickeau 337*37748cd8SNickeau /** 338*37748cd8SNickeau * Loads the given class or interface. 339*37748cd8SNickeau * 340*37748cd8SNickeau * @param string $class The name of the class 341*37748cd8SNickeau * @return bool|null True if loaded, null otherwise 342*37748cd8SNickeau */ 343*37748cd8SNickeau public function loadClass($class) 344*37748cd8SNickeau { 345*37748cd8SNickeau if ($file = $this->findFile($class)) { 346*37748cd8SNickeau includeFile($file); 347*37748cd8SNickeau 348*37748cd8SNickeau return true; 349*37748cd8SNickeau } 350*37748cd8SNickeau } 351*37748cd8SNickeau 352*37748cd8SNickeau /** 353*37748cd8SNickeau * Finds the path to the file where the class is defined. 354*37748cd8SNickeau * 355*37748cd8SNickeau * @param string $class The name of the class 356*37748cd8SNickeau * 357*37748cd8SNickeau * @return string|false The path if found, false otherwise 358*37748cd8SNickeau */ 359*37748cd8SNickeau public function findFile($class) 360*37748cd8SNickeau { 361*37748cd8SNickeau // class map lookup 362*37748cd8SNickeau if (isset($this->classMap[$class])) { 363*37748cd8SNickeau return $this->classMap[$class]; 364*37748cd8SNickeau } 365*37748cd8SNickeau if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { 366*37748cd8SNickeau return false; 367*37748cd8SNickeau } 368*37748cd8SNickeau if (null !== $this->apcuPrefix) { 369*37748cd8SNickeau $file = apcu_fetch($this->apcuPrefix.$class, $hit); 370*37748cd8SNickeau if ($hit) { 371*37748cd8SNickeau return $file; 372*37748cd8SNickeau } 373*37748cd8SNickeau } 374*37748cd8SNickeau 375*37748cd8SNickeau $file = $this->findFileWithExtension($class, '.php'); 376*37748cd8SNickeau 377*37748cd8SNickeau // Search for Hack files if we are running on HHVM 378*37748cd8SNickeau if (false === $file && defined('HHVM_VERSION')) { 379*37748cd8SNickeau $file = $this->findFileWithExtension($class, '.hh'); 380*37748cd8SNickeau } 381*37748cd8SNickeau 382*37748cd8SNickeau if (null !== $this->apcuPrefix) { 383*37748cd8SNickeau apcu_add($this->apcuPrefix.$class, $file); 384*37748cd8SNickeau } 385*37748cd8SNickeau 386*37748cd8SNickeau if (false === $file) { 387*37748cd8SNickeau // Remember that this class does not exist. 388*37748cd8SNickeau $this->missingClasses[$class] = true; 389*37748cd8SNickeau } 390*37748cd8SNickeau 391*37748cd8SNickeau return $file; 392*37748cd8SNickeau } 393*37748cd8SNickeau 394*37748cd8SNickeau /** 395*37748cd8SNickeau * Returns the currently registered loaders indexed by their corresponding vendor directories. 396*37748cd8SNickeau * 397*37748cd8SNickeau * @return self[] 398*37748cd8SNickeau */ 399*37748cd8SNickeau public static function getRegisteredLoaders() 400*37748cd8SNickeau { 401*37748cd8SNickeau return self::$registeredLoaders; 402*37748cd8SNickeau } 403*37748cd8SNickeau 404*37748cd8SNickeau private function findFileWithExtension($class, $ext) 405*37748cd8SNickeau { 406*37748cd8SNickeau // PSR-4 lookup 407*37748cd8SNickeau $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; 408*37748cd8SNickeau 409*37748cd8SNickeau $first = $class[0]; 410*37748cd8SNickeau if (isset($this->prefixLengthsPsr4[$first])) { 411*37748cd8SNickeau $subPath = $class; 412*37748cd8SNickeau while (false !== $lastPos = strrpos($subPath, '\\')) { 413*37748cd8SNickeau $subPath = substr($subPath, 0, $lastPos); 414*37748cd8SNickeau $search = $subPath . '\\'; 415*37748cd8SNickeau if (isset($this->prefixDirsPsr4[$search])) { 416*37748cd8SNickeau $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); 417*37748cd8SNickeau foreach ($this->prefixDirsPsr4[$search] as $dir) { 418*37748cd8SNickeau if (file_exists($file = $dir . $pathEnd)) { 419*37748cd8SNickeau return $file; 420*37748cd8SNickeau } 421*37748cd8SNickeau } 422*37748cd8SNickeau } 423*37748cd8SNickeau } 424*37748cd8SNickeau } 425*37748cd8SNickeau 426*37748cd8SNickeau // PSR-4 fallback dirs 427*37748cd8SNickeau foreach ($this->fallbackDirsPsr4 as $dir) { 428*37748cd8SNickeau if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { 429*37748cd8SNickeau return $file; 430*37748cd8SNickeau } 431*37748cd8SNickeau } 432*37748cd8SNickeau 433*37748cd8SNickeau // PSR-0 lookup 434*37748cd8SNickeau if (false !== $pos = strrpos($class, '\\')) { 435*37748cd8SNickeau // namespaced class name 436*37748cd8SNickeau $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) 437*37748cd8SNickeau . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); 438*37748cd8SNickeau } else { 439*37748cd8SNickeau // PEAR-like class name 440*37748cd8SNickeau $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; 441*37748cd8SNickeau } 442*37748cd8SNickeau 443*37748cd8SNickeau if (isset($this->prefixesPsr0[$first])) { 444*37748cd8SNickeau foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { 445*37748cd8SNickeau if (0 === strpos($class, $prefix)) { 446*37748cd8SNickeau foreach ($dirs as $dir) { 447*37748cd8SNickeau if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { 448*37748cd8SNickeau return $file; 449*37748cd8SNickeau } 450*37748cd8SNickeau } 451*37748cd8SNickeau } 452*37748cd8SNickeau } 453*37748cd8SNickeau } 454*37748cd8SNickeau 455*37748cd8SNickeau // PSR-0 fallback dirs 456*37748cd8SNickeau foreach ($this->fallbackDirsPsr0 as $dir) { 457*37748cd8SNickeau if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { 458*37748cd8SNickeau return $file; 459*37748cd8SNickeau } 460*37748cd8SNickeau } 461*37748cd8SNickeau 462*37748cd8SNickeau // PSR-0 include paths. 463*37748cd8SNickeau if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { 464*37748cd8SNickeau return $file; 465*37748cd8SNickeau } 466*37748cd8SNickeau 467*37748cd8SNickeau return false; 468*37748cd8SNickeau } 469*37748cd8SNickeau} 470*37748cd8SNickeau 471*37748cd8SNickeau/** 472*37748cd8SNickeau * Scope isolated include. 473*37748cd8SNickeau * 474*37748cd8SNickeau * Prevents access to $this/self from included files. 475*37748cd8SNickeau */ 476*37748cd8SNickeaufunction includeFile($file) 477*37748cd8SNickeau{ 478*37748cd8SNickeau include $file; 479*37748cd8SNickeau} 480