ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
ClassLoader.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of Composer.
5  *
6  * (c) Nils Adermann <naderman@naderman.de>
7  * Jordi Boggiano <j.boggiano@seld.be>
8  *
9  * For the full copyright and license information, please view the LICENSE
10  * file that was distributed with this source code.
11  */
12 
13 namespace Composer\Autoload;
14 
44 {
45  // PSR-4
47  private $prefixDirsPsr4 = array();
48  private $fallbackDirsPsr4 = array();
49 
50  // PSR-0
51  private $prefixesPsr0 = array();
52  private $fallbackDirsPsr0 = array();
53 
54  private $useIncludePath = false;
55  private $classMap = array();
56  private $classMapAuthoritative = false;
57  private $missingClasses = array();
58  private $apcuPrefix;
59 
60  public function getPrefixes()
61  {
62  if (!empty($this->prefixesPsr0)) {
63  return call_user_func_array('array_merge', $this->prefixesPsr0);
64  }
65 
66  return array();
67  }
68 
69  public function getPrefixesPsr4()
70  {
71  return $this->prefixDirsPsr4;
72  }
73 
74  public function getFallbackDirs()
75  {
77  }
78 
79  public function getFallbackDirsPsr4()
80  {
82  }
83 
84  public function getClassMap()
85  {
86  return $this->classMap;
87  }
88 
92  public function addClassMap(array $classMap)
93  {
94  if ($this->classMap) {
95  $this->classMap = array_merge($this->classMap, $classMap);
96  } else {
97  $this->classMap = $classMap;
98  }
99  }
100 
109  public function add($prefix, $paths, $prepend = false)
110  {
111  if (!$prefix) {
112  if ($prepend) {
113  $this->fallbackDirsPsr0 = array_merge(
114  (array) $paths,
115  $this->fallbackDirsPsr0
116  );
117  } else {
118  $this->fallbackDirsPsr0 = array_merge(
119  $this->fallbackDirsPsr0,
120  (array) $paths
121  );
122  }
123 
124  return;
125  }
126 
127  $first = $prefix[0];
128  if (!isset($this->prefixesPsr0[$first][$prefix])) {
129  $this->prefixesPsr0[$first][$prefix] = (array) $paths;
130 
131  return;
132  }
133  if ($prepend) {
134  $this->prefixesPsr0[$first][$prefix] = array_merge(
135  (array) $paths,
136  $this->prefixesPsr0[$first][$prefix]
137  );
138  } else {
139  $this->prefixesPsr0[$first][$prefix] = array_merge(
140  $this->prefixesPsr0[$first][$prefix],
141  (array) $paths
142  );
143  }
144  }
145 
156  public function addPsr4($prefix, $paths, $prepend = false)
157  {
158  if (!$prefix) {
159  // Register directories for the root namespace.
160  if ($prepend) {
161  $this->fallbackDirsPsr4 = array_merge(
162  (array) $paths,
163  $this->fallbackDirsPsr4
164  );
165  } else {
166  $this->fallbackDirsPsr4 = array_merge(
167  $this->fallbackDirsPsr4,
168  (array) $paths
169  );
170  }
171  } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
172  // Register directories for a new namespace.
173  $length = strlen($prefix);
174  if ('\\' !== $prefix[$length - 1]) {
175  throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
176  }
177  $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
178  $this->prefixDirsPsr4[$prefix] = (array) $paths;
179  } elseif ($prepend) {
180  // Prepend directories for an already registered namespace.
181  $this->prefixDirsPsr4[$prefix] = array_merge(
182  (array) $paths,
183  $this->prefixDirsPsr4[$prefix]
184  );
185  } else {
186  // Append directories for an already registered namespace.
187  $this->prefixDirsPsr4[$prefix] = array_merge(
188  $this->prefixDirsPsr4[$prefix],
189  (array) $paths
190  );
191  }
192  }
193 
201  public function set($prefix, $paths)
202  {
203  if (!$prefix) {
204  $this->fallbackDirsPsr0 = (array) $paths;
205  } else {
206  $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
207  }
208  }
209 
219  public function setPsr4($prefix, $paths)
220  {
221  if (!$prefix) {
222  $this->fallbackDirsPsr4 = (array) $paths;
223  } else {
224  $length = strlen($prefix);
225  if ('\\' !== $prefix[$length - 1]) {
226  throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
227  }
228  $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
229  $this->prefixDirsPsr4[$prefix] = (array) $paths;
230  }
231  }
232 
239  {
240  $this->useIncludePath = $useIncludePath;
241  }
242 
249  public function getUseIncludePath()
250  {
251  return $this->useIncludePath;
252  }
253 
261  {
262  $this->classMapAuthoritative = $classMapAuthoritative;
263  }
264 
270  public function isClassMapAuthoritative()
271  {
273  }
274 
280  public function setApcuPrefix($apcuPrefix)
281  {
282  $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
283  }
284 
290  public function getApcuPrefix()
291  {
292  return $this->apcuPrefix;
293  }
294 
300  public function register($prepend = false)
301  {
302  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
303  }
304 
308  public function unregister()
309  {
310  spl_autoload_unregister(array($this, 'loadClass'));
311  }
312 
319  public function loadClass($class)
320  {
321  if ($file = $this->findFile($class)) {
323 
324  return true;
325  }
326  }
327 
335  public function findFile($class)
336  {
337  // class map lookup
338  if (isset($this->classMap[$class])) {
339  return $this->classMap[$class];
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  }
350 
351  $file = $this->findFileWithExtension($class, '.php');
352 
353  // Search for Hack files if we are running on HHVM
354  if (false === $file && defined('HHVM_VERSION')) {
355  $file = $this->findFileWithExtension($class, '.hh');
356  }
357 
358  if (null !== $this->apcuPrefix) {
359  apcu_add($this->apcuPrefix.$class, $file);
360  }
361 
362  if (false === $file) {
363  // Remember that this class does not exist.
364  $this->missingClasses[$class] = true;
365  }
366 
367  return $file;
368  }
369 
370  private function findFileWithExtension($class, $ext)
371  {
372  // PSR-4 lookup
373  $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
374 
375  $first = $class[0];
376  if (isset($this->prefixLengthsPsr4[$first])) {
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  foreach ($this->prefixDirsPsr4[$search] as $dir) {
383  $length = $this->prefixLengthsPsr4[$first][$search];
384  if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
385  return $file;
386  }
387  }
388  }
389  }
390  }
391 
392  // PSR-4 fallback dirs
393  foreach ($this->fallbackDirsPsr4 as $dir) {
394  if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
395  return $file;
396  }
397  }
398 
399  // PSR-0 lookup
400  if (false !== $pos = strrpos($class, '\\')) {
401  // namespaced class name
402  $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
403  . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
404  } else {
405  // PEAR-like class name
406  $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
407  }
408 
409  if (isset($this->prefixesPsr0[$first])) {
410  foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
411  if (0 === strpos($class, $prefix)) {
412  foreach ($dirs as $dir) {
413  if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
414  return $file;
415  }
416  }
417  }
418  }
419  }
420 
421  // PSR-0 fallback dirs
422  foreach ($this->fallbackDirsPsr0 as $dir) {
423  if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
424  return $file;
425  }
426  }
427 
428  // PSR-0 include paths.
429  if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
430  return $file;
431  }
432 
433  return false;
434  }
435 }
436 
443 {
444  include $file;
445 }
loadClass($class)
Loads the given class or interface.
getUseIncludePath()
Can be used to check if the autoloader uses the include path to check for classes.
setUseIncludePath($useIncludePath)
Turns on searching the include path for class files.
getApcuPrefix()
The APCu prefix in use, or null if APCu caching is not enabled.
add($prefix, $paths, $prepend=false)
Registers a set of PSR-0 directories for a given prefix, either appending or prepending to the ones p...
setApcuPrefix($apcuPrefix)
APCu prefix to use to cache found/not-found classes, if the extension is enabled. ...
setClassMapAuthoritative($classMapAuthoritative)
Turns off searching the prefix and fallback directories for classes that have not been registered wit...
addPsr4($prefix, $paths, $prepend=false)
Registers a set of PSR-4 directories for a given namespace, either appending or prepending to the one...
findFileWithExtension($class, $ext)
unregister()
Unregisters this instance as an autoloader.
addClassMap(array $classMap)
Definition: ClassLoader.php:92
Create styles array
The data for the language used.
setPsr4($prefix, $paths)
Registers a set of PSR-4 directories for a given namespace, replacing any others previously set for t...
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
includeFile($file)
Scope isolated include.
isClassMapAuthoritative()
Should class lookup fail if not found in the current class map?
defined( 'APPLICATION_ENV')||define( 'APPLICATION_ENV'
Definition: bootstrap.php:27
ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
Definition: ClassLoader.php:43
findFile($class)
Finds the path to the file where the class is defined.