ComposerAutoloadClassLoader

ClassLoader implements a PSR-0 class loader.

Defined (1)

The class is defined in the following location(s).

/vendor/composer/ClassLoader.php  
  1. class ClassLoader 
  2. // PSR-4 
  3. private $prefixLengthsPsr4 = array(); 
  4. private $prefixDirsPsr4 = array(); 
  5. private $fallbackDirsPsr4 = array(); 
  6.  
  7. // PSR-0 
  8. private $prefixesPsr0 = array(); 
  9. private $fallbackDirsPsr0 = array(); 
  10.  
  11. private $useIncludePath = false; 
  12. private $classMap = array(); 
  13. private $classMapAuthoritative = false; 
  14. private $missingClasses = array(); 
  15. private $apcuPrefix; 
  16.  
  17. public function getPrefixes() 
  18. if (!empty($this->prefixesPsr0)) { 
  19. return call_user_func_array('array_merge', $this->prefixesPsr0); 
  20.  
  21. return array(); 
  22.  
  23. public function getPrefixesPsr4() 
  24. return $this->prefixDirsPsr4; 
  25.  
  26. public function getFallbackDirs() 
  27. return $this->fallbackDirsPsr0; 
  28.  
  29. public function getFallbackDirsPsr4() 
  30. return $this->fallbackDirsPsr4; 
  31.  
  32. public function getClassMap() 
  33. return $this->classMap; 
  34.  
  35. /** 
  36. * @param array $classMap Class to filename map 
  37. */ 
  38. public function addClassMap(array $classMap) 
  39. if ($this->classMap) { 
  40. $this->classMap = array_merge($this->classMap, $classMap); 
  41. } else { 
  42. $this->classMap = $classMap; 
  43.  
  44. /** 
  45. * Registers a set of PSR-0 directories for a given prefix, either 
  46. * appending or prepending to the ones previously set for this prefix. 
  47. * @param string $prefix The prefix 
  48. * @param array|string $paths The PSR-0 root directories 
  49. * @param bool $prepend Whether to prepend the directories 
  50. */ 
  51. public function add($prefix, $paths, $prepend = false) 
  52. if (!$prefix) { 
  53. if ($prepend) { 
  54. $this->fallbackDirsPsr0 = array_merge( 
  55. (array) $paths,  
  56. $this->fallbackDirsPsr0 
  57. ); 
  58. } else { 
  59. $this->fallbackDirsPsr0 = array_merge( 
  60. $this->fallbackDirsPsr0,  
  61. (array) $paths 
  62. ); 
  63.  
  64. return; 
  65.  
  66. $first = $prefix[0]; 
  67. if (!isset($this->prefixesPsr0[$first][$prefix])) { 
  68. $this->prefixesPsr0[$first][$prefix] = (array) $paths; 
  69.  
  70. return; 
  71. if ($prepend) { 
  72. $this->prefixesPsr0[$first][$prefix] = array_merge( 
  73. (array) $paths,  
  74. $this->prefixesPsr0[$first][$prefix] 
  75. ); 
  76. } else { 
  77. $this->prefixesPsr0[$first][$prefix] = array_merge( 
  78. $this->prefixesPsr0[$first][$prefix],  
  79. (array) $paths 
  80. ); 
  81.  
  82. /** 
  83. * Registers a set of PSR-4 directories for a given namespace, either 
  84. * appending or prepending to the ones previously set for this namespace. 
  85. * @param string $prefix The prefix/namespace, with trailing '\\' 
  86. * @param array|string $paths The PSR-4 base directories 
  87. * @param bool $prepend Whether to prepend the directories 
  88. * @throws \InvalidArgumentException 
  89. */ 
  90. public function addPsr4($prefix, $paths, $prepend = false) 
  91. if (!$prefix) { 
  92. // Register directories for the root namespace. 
  93. if ($prepend) { 
  94. $this->fallbackDirsPsr4 = array_merge( 
  95. (array) $paths,  
  96. $this->fallbackDirsPsr4 
  97. ); 
  98. } else { 
  99. $this->fallbackDirsPsr4 = array_merge( 
  100. $this->fallbackDirsPsr4,  
  101. (array) $paths 
  102. ); 
  103. } elseif (!isset($this->prefixDirsPsr4[$prefix])) { 
  104. // Register directories for a new namespace. 
  105. $length = strlen($prefix); 
  106. if ('\\' !== $prefix[$length - 1]) { 
  107. throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); 
  108. $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; 
  109. $this->prefixDirsPsr4[$prefix] = (array) $paths; 
  110. } elseif ($prepend) { 
  111. // Prepend directories for an already registered namespace. 
  112. $this->prefixDirsPsr4[$prefix] = array_merge( 
  113. (array) $paths,  
  114. $this->prefixDirsPsr4[$prefix] 
  115. ); 
  116. } else { 
  117. // Append directories for an already registered namespace. 
  118. $this->prefixDirsPsr4[$prefix] = array_merge( 
  119. $this->prefixDirsPsr4[$prefix],  
  120. (array) $paths 
  121. ); 
  122.  
  123. /** 
  124. * Registers a set of PSR-0 directories for a given prefix,  
  125. * replacing any others previously set for this prefix. 
  126. * @param string $prefix The prefix 
  127. * @param array|string $paths The PSR-0 base directories 
  128. */ 
  129. public function set($prefix, $paths) 
  130. if (!$prefix) { 
  131. $this->fallbackDirsPsr0 = (array) $paths; 
  132. } else { 
  133. $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; 
  134.  
  135. /** 
  136. * Registers a set of PSR-4 directories for a given namespace,  
  137. * replacing any others previously set for this namespace. 
  138. * @param string $prefix The prefix/namespace, with trailing '\\' 
  139. * @param array|string $paths The PSR-4 base directories 
  140. * @throws \InvalidArgumentException 
  141. */ 
  142. public function setPsr4($prefix, $paths) 
  143. if (!$prefix) { 
  144. $this->fallbackDirsPsr4 = (array) $paths; 
  145. } else { 
  146. $length = strlen($prefix); 
  147. if ('\\' !== $prefix[$length - 1]) { 
  148. throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); 
  149. $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; 
  150. $this->prefixDirsPsr4[$prefix] = (array) $paths; 
  151.  
  152. /** 
  153. * Turns on searching the include path for class files. 
  154. * @param bool $useIncludePath 
  155. */ 
  156. public function setUseIncludePath($useIncludePath) 
  157. $this->useIncludePath = $useIncludePath; 
  158.  
  159. /** 
  160. * Can be used to check if the autoloader uses the include path to check 
  161. * for classes. 
  162. * @return bool 
  163. */ 
  164. public function getUseIncludePath() 
  165. return $this->useIncludePath; 
  166.  
  167. /** 
  168. * Turns off searching the prefix and fallback directories for classes 
  169. * that have not been registered with the class map. 
  170. * @param bool $classMapAuthoritative 
  171. */ 
  172. public function setClassMapAuthoritative($classMapAuthoritative) 
  173. $this->classMapAuthoritative = $classMapAuthoritative; 
  174.  
  175. /** 
  176. * Should class lookup fail if not found in the current class map? 
  177. * @return bool 
  178. */ 
  179. public function isClassMapAuthoritative() 
  180. return $this->classMapAuthoritative; 
  181.  
  182. /** 
  183. * APCu prefix to use to cache found/not-found classes, if the extension is enabled. 
  184. * @param string|null $apcuPrefix 
  185. */ 
  186. public function setApcuPrefix($apcuPrefix) 
  187. $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; 
  188.  
  189. /** 
  190. * The APCu prefix in use, or null if APCu caching is not enabled. 
  191. * @return string|null 
  192. */ 
  193. public function getApcuPrefix() 
  194. return $this->apcuPrefix; 
  195.  
  196. /** 
  197. * Registers this instance as an autoloader. 
  198. * @param bool $prepend Whether to prepend the autoloader or not 
  199. */ 
  200. public function register($prepend = false) 
  201. spl_autoload_register(array($this, 'loadClass'), true, $prepend); 
  202.  
  203. /** 
  204. * Unregisters this instance as an autoloader. 
  205. */ 
  206. public function unregister() 
  207. spl_autoload_unregister(array($this, 'loadClass')); 
  208.  
  209. /** 
  210. * Loads the given class or interface. 
  211. * @param string $class The name of the class 
  212. * @return bool|null True if loaded, null otherwise 
  213. */ 
  214. public function loadClass($class) 
  215. if ($file = $this->findFile($class)) { 
  216. includeFile($file); 
  217.  
  218. return true; 
  219.  
  220. /** 
  221. * Finds the path to the file where the class is defined. 
  222. * @param string $class The name of the class 
  223. * @return string|false The path if found, false otherwise 
  224. */ 
  225. public function findFile($class) 
  226. // class map lookup 
  227. if (isset($this->classMap[$class])) { 
  228. return $this->classMap[$class]; 
  229. if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { 
  230. return false; 
  231. if (null !== $this->apcuPrefix) { 
  232. $file = apcu_fetch($this->apcuPrefix.$class, $hit); 
  233. if ($hit) { 
  234. return $file; 
  235.  
  236. $file = $this->findFileWithExtension($class, '.php'); 
  237.  
  238. // Search for Hack files if we are running on HHVM 
  239. if (false === $file && defined('HHVM_VERSION')) { 
  240. $file = $this->findFileWithExtension($class, '.hh'); 
  241.  
  242. if (null !== $this->apcuPrefix) { 
  243. apcu_add($this->apcuPrefix.$class, $file); 
  244.  
  245. if (false === $file) { 
  246. // Remember that this class does not exist. 
  247. $this->missingClasses[$class] = true; 
  248.  
  249. return $file; 
  250.  
  251. private function findFileWithExtension($class, $ext) 
  252. // PSR-4 lookup 
  253. $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; 
  254.  
  255. $first = $class[0]; 
  256. if (isset($this->prefixLengthsPsr4[$first])) { 
  257. foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { 
  258. if (0 === strpos($class, $prefix)) { 
  259. foreach ($this->prefixDirsPsr4[$prefix] as $dir) { 
  260. if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { 
  261. return $file; 
  262.  
  263. // PSR-4 fallback dirs 
  264. foreach ($this->fallbackDirsPsr4 as $dir) { 
  265. if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { 
  266. return $file; 
  267.  
  268. // PSR-0 lookup 
  269. if (false !== $pos = strrpos($class, '\\')) { 
  270. // namespaced class name 
  271. $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) 
  272. . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); 
  273. } else { 
  274. // PEAR-like class name 
  275. $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; 
  276.  
  277. if (isset($this->prefixesPsr0[$first])) { 
  278. foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { 
  279. if (0 === strpos($class, $prefix)) { 
  280. foreach ($dirs as $dir) { 
  281. if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { 
  282. return $file; 
  283.  
  284. // PSR-0 fallback dirs 
  285. foreach ($this->fallbackDirsPsr0 as $dir) { 
  286. if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { 
  287. return $file; 
  288.  
  289. // PSR-0 include paths. 
  290. if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { 
  291. return $file; 
  292.  
  293. return false;