4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\ClassLoader
;
15 * UniversalClassLoader implements a "universal" autoloader for PHP 5.3.
17 * It is able to load classes that use either:
19 * * The technical interoperability standards for PHP 5.3 namespaces and
20 * class names (https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md);
22 * * The PEAR naming convention for classes (http://pear.php.net/).
24 * Classes from a sub-namespace or a sub-hierarchy of PEAR classes can be
25 * looked for in a list of locations to ease the vendoring of a sub-set of
26 * classes for large projects.
30 * $loader = new UniversalClassLoader();
32 * // register classes with namespaces
33 * $loader->registerNamespaces(array(
34 * 'Symfony\Component' => __DIR__.'/component',
35 * 'Symfony' => __DIR__.'/framework',
36 * 'Sensio' => array(__DIR__.'/src', __DIR__.'/vendor'),
39 * // register a library using the PEAR naming convention
40 * $loader->registerPrefixes(array(
41 * 'Swift_' => __DIR__.'/Swift',
44 * // activate the autoloader
45 * $loader->register();
47 * In this example, if you try to use a class in the Symfony\Component
48 * namespace or one of its children (Symfony\Component\Console for instance),
49 * the autoloader will first look for the class under the component/
50 * directory, and it will then fallback to the framework/ directory if not
51 * found before giving up.
53 * @author Fabien Potencier <fabien@symfony.com>
57 class UniversalClassLoader
59 private
$namespaces = array();
60 private
$prefixes = array();
61 private
$namespaceFallbacks = array();
62 private
$prefixFallbacks = array();
65 * Gets the configured namespaces.
67 * @return array A hash with namespaces as keys and directories as values
69 public
function getNamespaces()
71 return $this->namespaces
;
75 * Gets the configured class prefixes.
77 * @return array A hash with class prefixes as keys and directories as values
79 public
function getPrefixes()
81 return $this->prefixes
;
85 * Gets the directory(ies) to use as a fallback for namespaces.
87 * @return array An array of directories
89 public
function getNamespaceFallbacks()
91 return $this->namespaceFallbacks
;
95 * Gets the directory(ies) to use as a fallback for class prefixes.
97 * @return array An array of directories
99 public
function getPrefixFallbacks()
101 return $this->prefixFallbacks
;
105 * Registers the directory to use as a fallback for namespaces.
107 * @param array $dirs An array of directories
111 public
function registerNamespaceFallbacks(array $dirs)
113 $this->namespaceFallbacks
= $dirs;
117 * Registers the directory to use as a fallback for class prefixes.
119 * @param array $dirs An array of directories
123 public
function registerPrefixFallbacks(array $dirs)
125 $this->prefixFallbacks
= $dirs;
129 * Registers an array of namespaces
131 * @param array $namespaces An array of namespaces (namespaces as keys and locations as values)
135 public
function registerNamespaces(array $namespaces)
137 foreach ($namespaces as
$namespace => $locations) {
138 $this->namespaces
[$namespace] = (array) $locations;
143 * Registers a namespace.
145 * @param string $namespace The namespace
146 * @param array|string $paths The location(s) of the namespace
150 public
function registerNamespace($namespace, $paths)
152 $this->namespaces
[$namespace] = (array) $paths;
156 * Registers an array of classes using the PEAR naming convention.
158 * @param array $classes An array of classes (prefixes as keys and locations as values)
162 public
function registerPrefixes(array $classes)
164 foreach ($classes as
$prefix => $locations) {
165 $this->prefixes
[$prefix] = (array) $locations;
170 * Registers a set of classes using the PEAR naming convention.
172 * @param string $prefix The classes prefix
173 * @param array|string $paths The location(s) of the classes
177 public
function registerPrefix($prefix, $paths)
179 $this->prefixes
[$prefix] = (array) $paths;
183 * Registers this instance as an autoloader.
185 * @param Boolean $prepend Whether to prepend the autoloader or not
189 public
function register($prepend = false
)
191 spl_autoload_register(array($this, 'loadClass'), true
, $prepend);
195 * Loads the given class or interface.
197 * @param string $class The name of the class
199 public
function loadClass($class)
201 if ($file = $this->findFile($class)) {
207 * Finds the path to the file where the class is defined.
209 * @param string $class The name of the class
211 * @return string|null The path, if found
213 public
function findFile($class)
215 if ('\\' == $class[0]) {
216 $class = substr($class, 1);
219 if (false
!== $pos = strrpos($class, '\\')) {
220 // namespaced class name
221 $namespace = substr($class, 0, $pos);
222 foreach ($this->namespaces as
$ns => $dirs) {
223 if (0 !== strpos($namespace, $ns)) {
227 foreach ($dirs as
$dir) {
228 $className = substr($class, $pos + 1);
229 $file = $dir.DIRECTORY_SEPARATOR.
str_replace('\\', DIRECTORY_SEPARATOR
, $namespace).DIRECTORY_SEPARATOR.
str_replace('_', DIRECTORY_SEPARATOR
, $className).
'.php';
230 if (file_exists($file)) {
236 foreach ($this->namespaceFallbacks as
$dir) {
237 $file = $dir.DIRECTORY_SEPARATOR.
str_replace('\\', DIRECTORY_SEPARATOR
, $class).
'.php';
238 if (file_exists($file)) {
243 // PEAR-like class name
244 foreach ($this->prefixes as
$prefix => $dirs) {
245 if (0 !== strpos($class, $prefix)) {
249 foreach ($dirs as
$dir) {
250 $file = $dir.DIRECTORY_SEPARATOR.
str_replace('_', DIRECTORY_SEPARATOR
, $class).
'.php';
251 if (file_exists($file)) {
257 foreach ($this->prefixFallbacks as
$dir) {
258 $file = $dir.DIRECTORY_SEPARATOR.
str_replace('_', DIRECTORY_SEPARATOR
, $class).
'.php';
259 if (file_exists($file)) {