/
UniversalClassLoader.php
147 lines (136 loc) · 3.98 KB
/
UniversalClassLoader.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<?php
namespace Symfony\Foundation;
/*
* This file is part of the symfony package.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* UniversalClassLoader implements a "universal" autoloder for PHP 5.3.
*
* It is able to load classes that use either:
*
* * The technical interoperability standards for PHP 5.3 namespaces and
* class names (http://groups.google.com/group/php-standards/web/final-proposal);
*
* * The PEAR naming convention for classes (http://pear.php.net/).
*
* Classes from a sub-namespace or a sub-hierarchy of PEAR classes can be
* looked for in a list of locations to ease the vendoring of a sub-set of
* classes for large projects.
*
* Example usage:
*
* $loader = new ClassLoader();
*
* // register classes with namespaces
* $loader->registerNamespaces(array(
* 'Symfony\Components' => __DIR__.'/components',
* 'Symfony' => __DIR__.'/framework',
* ));
*
* // register a library using the PEAR naming convention
* $loader->registerClasses(array(
* 'Swift_' => __DIR__.'/Swift',
* ));
*
* // activate the autoloader
* $loader->register();
*
* In this example, if you try to use a class in the Symfony\Components
* namespace or one of its children (Symfony\Components\Console for instance),
* the autoloader will first look for the class under the components/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* @package symfony
* @subpackage foundation
* @author Fabien Potencier <fabien.potencier@symfony-project.org>
*/
class UniversalClassLoader
{
protected $namespaces = array();
protected $prefixes = array();
/**
* Registers an array of namespaces
*
* @param array $namespaces An array of namespaces (namespaces as keys and locations as values)
*/
public function registerNamespaces(array $namespaces)
{
$this->namespaces = array_merge($this->namespaces, $namespaces);
}
/**
* Registers a namespace.
*
* @param string $namespace The namespace
* @param string $path The location of the namespace
*/
public function registerNamespace($namespace, $path)
{
$this->namespaces[$namespace] = $path;
}
/**
* Registers an array of classes using the PEAR naming convention.
*
* @param array $classes An array of classes (prefixes as keys and locations as values)
*/
public function registerPrefixes(array $classes)
{
$this->prefixes = array_merge($this->prefixes, $classes);
}
/**
* Registers a set of classes using the PEAR naming convention.
*
* @param string $prefix The classes prefix
* @param string $path The location of the classes
*/
public function registerPrefix($prefix, $path)
{
$this->prefixes[$prefix] = $path;
}
/**
* Registers this instance as an autoloader.
*/
public function register()
{
spl_autoload_register(array($this, 'loadClass'));
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
*/
public function loadClass($class)
{
if (false !== ($pos = strripos($class, '\\')))
{
// namespaced class name
$namespace = substr($class, 0, $pos);
foreach ($this->namespaces as $ns => $dir)
{
if (0 === strpos($namespace, $ns))
{
$class = substr($class, $pos + 1);
require $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
return;
}
}
}
else
{
// PEAR-like class name
foreach ($this->prefixes as $prefix => $dir)
{
if (0 === strpos($class, $prefix))
{
require $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
return;
}
}
}
}
}