* * 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->registerPrefixes(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 */ 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; } } } } }