浏览代码

[ClassLoader] added the possibility to define more than one directory for a namespace or a prefix

Fabien Potencier 14 年之前
父节点
当前提交
2d69369c69

+ 53 - 42
src/Symfony/Component/ClassLoader/UniversalClassLoader.php

@@ -31,13 +31,14 @@ namespace Symfony\Component\ClassLoader;
  *
  *     // register classes with namespaces
  *     $loader->registerNamespaces(array(
- *       'Symfony\Component' => __DIR__.'/component',
- *       'Symfony' => __DIR__.'/framework',
+ *         'Symfony\Component' => __DIR__.'/component',
+ *         'Symfony'           => __DIR__.'/framework',
+ *         'Sensio'            => array(__DIR__.'/src', __DIR__.'/vendor'),
  *     ));
  *
  *     // register a library using the PEAR naming convention
  *     $loader->registerPrefixes(array(
- *       'Swift_' => __DIR__.'/Swift',
+ *         'Swift_' => __DIR__.'/Swift',
  *     ));
  *
  *     // activate the autoloader
@@ -55,8 +56,8 @@ class UniversalClassLoader
 {
     protected $namespaces = array();
     protected $prefixes = array();
-    protected $namespaceFallback;
-    protected $prefixFallback;
+    protected $namespaceFallback = array();
+    protected $prefixFallback = array();
 
     /**
      * Gets the configured namespaces.
@@ -79,9 +80,9 @@ class UniversalClassLoader
     }
 
     /**
-     * Gets the directory to use as a fallback for namespaces.
+     * Gets the directory(ies) to use as a fallback for namespaces.
      *
-     * @return string A directory path
+     * @return array An array of directories
      */
     public function getNamespaceFallback()
     {
@@ -89,9 +90,9 @@ class UniversalClassLoader
     }
 
     /**
-     * Gets the directory to use as a fallback for class prefixes.
+     * Gets the directory(ies) to use as a fallback for class prefixes.
      *
-     * @return string A directory path
+     * @return array An array of directories
      */
     public function getPrefixFallback()
     {
@@ -101,21 +102,21 @@ class UniversalClassLoader
     /**
      * Registers the directory to use as a fallback for namespaces.
      *
-     * @return string $dir A directory path
+     * @return string|array $dirs A directory path or an array of directories
      */
-    public function registerNamespaceFallback($dir)
+    public function registerNamespaceFallback($dirs)
     {
-        $this->namespaceFallback = $dir;
+        $this->namespaceFallback = (array) $dirs;
     }
 
     /**
      * Registers the directory to use as a fallback for class prefixes.
      *
-     * @param string $dir A directory path
+     * @return string|array $dirs A directory path or an array of directories
      */
-    public function registerPrefixFallback($dir)
+    public function registerPrefixFallback($dirs)
     {
-        $this->prefixFallback = $dir;
+        $this->prefixFallback = (array) $dirs;
     }
 
     /**
@@ -125,18 +126,20 @@ class UniversalClassLoader
      */
     public function registerNamespaces(array $namespaces)
     {
-        $this->namespaces = array_merge($this->namespaces, $namespaces);
+        foreach ($namespaces as $namespace => $locations) {
+            $this->namespaces[$namespace] = (array) $locations;
+        }
     }
 
     /**
      * Registers a namespace.
      *
-     * @param string $namespace The namespace
-     * @param string $path      The location of the namespace
+     * @param string       $namespace The namespace
+     * @param array|string $paths     The location(s) of the namespace
      */
-    public function registerNamespace($namespace, $path)
+    public function registerNamespace($namespace, $paths)
     {
-        $this->namespaces[$namespace] = $path;
+        $this->namespaces[$namespace] = (array) $paths;
     }
 
     /**
@@ -146,18 +149,20 @@ class UniversalClassLoader
      */
     public function registerPrefixes(array $classes)
     {
-        $this->prefixes = array_merge($this->prefixes, $classes);
+        foreach ($classes as $prefix => $locations) {
+            $this->prefixes[$prefix] = (array) $locations;
+        }
     }
 
     /**
      * Registers a set of classes using the PEAR naming convention.
      *
-     * @param string $prefix The classes prefix
-     * @param string $path   The location of the classes
+     * @param string       $prefix  The classes prefix
+     * @param array|string $paths   The location(s) of the classes
      */
-    public function registerPrefix($prefix, $path)
+    public function registerPrefix($prefix, $paths)
     {
-        $this->prefixes[$prefix] = $path;
+        $this->prefixes[$prefix] = (array) $paths;
     }
 
     /**
@@ -182,39 +187,45 @@ class UniversalClassLoader
         if (false !== ($pos = strripos($class, '\\'))) {
             // namespaced class name
             $namespace = substr($class, 0, $pos);
-            foreach ($this->namespaces as $ns => $dir) {
-                if (0 === strpos($namespace, $ns)) {
-                    $className = substr($class, $pos + 1);
-                    $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php';
-                    if (file_exists($file)) {
-                        require $file;
-                        return;
+            foreach ($this->namespaces as $ns => $dirs) {
+                foreach ($dirs as $dir) {
+                    if (0 === strpos($namespace, $ns)) {
+                        $className = substr($class, $pos + 1);
+                        $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php';
+                        if (file_exists($file)) {
+                            require $file;
+                            return;
+                        }
                     }
                 }
             }
 
-            if (null !== $this->namespaceFallback) {
-                $file = $this->namespaceFallback.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
+            foreach ($this->namespaceFallback as $dir) {
+                $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
                 if (file_exists($file)) {
                     require $file;
+                    return;
                 }
             }
         } else {
             // PEAR-like class name
-            foreach ($this->prefixes as $prefix => $dir) {
-                if (0 === strpos($class, $prefix)) {
-                    $file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
-                    if (file_exists($file)) {
-                        require $file;
-                        return;
+            foreach ($this->prefixes as $prefix => $dirs) {
+                foreach ($dirs as $dir) {
+                    if (0 === strpos($class, $prefix)) {
+                        $file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
+                        if (file_exists($file)) {
+                            require $file;
+                            return;
+                        }
                     }
                 }
             }
 
-            if (null !== $this->prefixFallback) {
-                $file = $this->prefixFallback.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
+            foreach ($this->prefixFallback as $dir) {
+                $file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
                 if (file_exists($file)) {
                     require $file;
+                    return;
                 }
             }
         }

+ 39 - 29
src/Symfony/Component/HttpKernel/bootstrap.php

@@ -1918,8 +1918,8 @@ class UniversalClassLoader
 {
     protected $namespaces = array();
     protected $prefixes = array();
-    protected $namespaceFallback;
-    protected $prefixFallback;
+    protected $namespaceFallback = array();
+    protected $prefixFallback = array();
     public function getNamespaces()
     {
         return $this->namespaces;
@@ -1936,29 +1936,33 @@ class UniversalClassLoader
     {
         return $this->prefixFallback;
     }
-    public function registerNamespaceFallback($dir)
+    public function registerNamespaceFallback($dirs)
     {
-        $this->namespaceFallback = $dir;
+        $this->namespaceFallback = (array) $dirs;
     }
-    public function registerPrefixFallback($dir)
+    public function registerPrefixFallback($dirs)
     {
-        $this->prefixFallback = $dir;
+        $this->prefixFallback = (array) $dirs;
     }
     public function registerNamespaces(array $namespaces)
     {
-        $this->namespaces = array_merge($this->namespaces, $namespaces);
+        foreach ($namespaces as $namespace => $locations) {
+            $this->namespaces[$namespace] = (array) $locations;
+        }
     }
-    public function registerNamespace($namespace, $path)
+    public function registerNamespace($namespace, $paths)
     {
-        $this->namespaces[$namespace] = $path;
+        $this->namespaces[$namespace] = (array) $paths;
     }
     public function registerPrefixes(array $classes)
     {
-        $this->prefixes = array_merge($this->prefixes, $classes);
+        foreach ($classes as $prefix => $locations) {
+            $this->prefixes[$prefix] = (array) $locations;
+        }
     }
-    public function registerPrefix($prefix, $path)
+    public function registerPrefix($prefix, $paths)
     {
-        $this->prefixes[$prefix] = $path;
+        $this->prefixes[$prefix] = (array) $paths;
     }
     public function register($prepend = false)
     {
@@ -1969,36 +1973,42 @@ class UniversalClassLoader
         $class = ltrim($class, '\\');
         if (false !== ($pos = strripos($class, '\\'))) {
                         $namespace = substr($class, 0, $pos);
-            foreach ($this->namespaces as $ns => $dir) {
-                if (0 === strpos($namespace, $ns)) {
-                    $className = substr($class, $pos + 1);
-                    $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php';
-                    if (file_exists($file)) {
-                        require $file;
-                        return;
+            foreach ($this->namespaces as $ns => $dirs) {
+                foreach ($dirs as $dir) {
+                    if (0 === strpos($namespace, $ns)) {
+                        $className = substr($class, $pos + 1);
+                        $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php';
+                        if (file_exists($file)) {
+                            require $file;
+                            return;
+                        }
                     }
                 }
             }
-            if (null !== $this->namespaceFallback) {
-                $file = $this->namespaceFallback.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
+            foreach ($this->namespaceFallback as $dir) {
+                $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
                 if (file_exists($file)) {
                     require $file;
+                    return;
                 }
             }
         } else {
-                        foreach ($this->prefixes as $prefix => $dir) {
-                if (0 === strpos($class, $prefix)) {
-                    $file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
-                    if (file_exists($file)) {
-                        require $file;
-                        return;
+                        foreach ($this->prefixes as $prefix => $dirs) {
+                foreach ($dirs as $dir) {
+                    if (0 === strpos($class, $prefix)) {
+                        $file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
+                        if (file_exists($file)) {
+                            require $file;
+                            return;
+                        }
                     }
                 }
             }
-            if (null !== $this->prefixFallback) {
-                $file = $this->prefixFallback.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
+            foreach ($this->prefixFallback as $dir) {
+                $file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
                 if (file_exists($file)) {
                     require $file;
+                    return;
                 }
             }
         }

+ 39 - 29
src/Symfony/Component/HttpKernel/bootstrap_cache.php

@@ -2379,8 +2379,8 @@ class UniversalClassLoader
 {
     protected $namespaces = array();
     protected $prefixes = array();
-    protected $namespaceFallback;
-    protected $prefixFallback;
+    protected $namespaceFallback = array();
+    protected $prefixFallback = array();
     public function getNamespaces()
     {
         return $this->namespaces;
@@ -2397,29 +2397,33 @@ class UniversalClassLoader
     {
         return $this->prefixFallback;
     }
-    public function registerNamespaceFallback($dir)
+    public function registerNamespaceFallback($dirs)
     {
-        $this->namespaceFallback = $dir;
+        $this->namespaceFallback = (array) $dirs;
     }
-    public function registerPrefixFallback($dir)
+    public function registerPrefixFallback($dirs)
     {
-        $this->prefixFallback = $dir;
+        $this->prefixFallback = (array) $dirs;
     }
     public function registerNamespaces(array $namespaces)
     {
-        $this->namespaces = array_merge($this->namespaces, $namespaces);
+        foreach ($namespaces as $namespace => $locations) {
+            $this->namespaces[$namespace] = (array) $locations;
+        }
     }
-    public function registerNamespace($namespace, $path)
+    public function registerNamespace($namespace, $paths)
     {
-        $this->namespaces[$namespace] = $path;
+        $this->namespaces[$namespace] = (array) $paths;
     }
     public function registerPrefixes(array $classes)
     {
-        $this->prefixes = array_merge($this->prefixes, $classes);
+        foreach ($classes as $prefix => $locations) {
+            $this->prefixes[$prefix] = (array) $locations;
+        }
     }
-    public function registerPrefix($prefix, $path)
+    public function registerPrefix($prefix, $paths)
     {
-        $this->prefixes[$prefix] = $path;
+        $this->prefixes[$prefix] = (array) $paths;
     }
     public function register($prepend = false)
     {
@@ -2430,36 +2434,42 @@ class UniversalClassLoader
         $class = ltrim($class, '\\');
         if (false !== ($pos = strripos($class, '\\'))) {
                         $namespace = substr($class, 0, $pos);
-            foreach ($this->namespaces as $ns => $dir) {
-                if (0 === strpos($namespace, $ns)) {
-                    $className = substr($class, $pos + 1);
-                    $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php';
-                    if (file_exists($file)) {
-                        require $file;
-                        return;
+            foreach ($this->namespaces as $ns => $dirs) {
+                foreach ($dirs as $dir) {
+                    if (0 === strpos($namespace, $ns)) {
+                        $className = substr($class, $pos + 1);
+                        $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $namespace).DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $className).'.php';
+                        if (file_exists($file)) {
+                            require $file;
+                            return;
+                        }
                     }
                 }
             }
-            if (null !== $this->namespaceFallback) {
-                $file = $this->namespaceFallback.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
+            foreach ($this->namespaceFallback as $dir) {
+                $file = $dir.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php';
                 if (file_exists($file)) {
                     require $file;
+                    return;
                 }
             }
         } else {
-                        foreach ($this->prefixes as $prefix => $dir) {
-                if (0 === strpos($class, $prefix)) {
-                    $file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
-                    if (file_exists($file)) {
-                        require $file;
-                        return;
+                        foreach ($this->prefixes as $prefix => $dirs) {
+                foreach ($dirs as $dir) {
+                    if (0 === strpos($class, $prefix)) {
+                        $file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
+                        if (file_exists($file)) {
+                            require $file;
+                            return;
+                        }
                     }
                 }
             }
-            if (null !== $this->prefixFallback) {
-                $file = $this->prefixFallback.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
+            foreach ($this->prefixFallback as $dir) {
+                $file = $dir.DIRECTORY_SEPARATOR.str_replace('_', DIRECTORY_SEPARATOR, $class).'.php';
                 if (file_exists($file)) {
                     require $file;
+                    return;
                 }
             }
         }