annotate vendor/doctrine/common/lib/Doctrine/Common/ClassLoader.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 <?php
Chris@0 2 /*
Chris@0 3 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Chris@0 4 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Chris@0 5 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Chris@0 6 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Chris@0 7 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Chris@0 8 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Chris@0 9 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Chris@0 10 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Chris@0 11 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Chris@0 12 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Chris@0 13 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Chris@0 14 *
Chris@0 15 * This software consists of voluntary contributions made by many individuals
Chris@0 16 * and is licensed under the MIT license. For more information, see
Chris@0 17 * <http://www.doctrine-project.org>.
Chris@0 18 */
Chris@0 19
Chris@0 20 namespace Doctrine\Common;
Chris@0 21
Chris@0 22 /**
Chris@0 23 * A <tt>ClassLoader</tt> is an autoloader for class files that can be
Chris@0 24 * installed on the SPL autoload stack. It is a class loader that either loads only classes
Chris@0 25 * of a specific namespace or all namespaces and it is suitable for working together
Chris@0 26 * with other autoloaders in the SPL autoload stack.
Chris@0 27 *
Chris@0 28 * If no include path is configured through the constructor or {@link setIncludePath}, a ClassLoader
Chris@0 29 * relies on the PHP <code>include_path</code>.
Chris@0 30 *
Chris@0 31 * @author Roman Borschel <roman@code-factory.org>
Chris@0 32 * @since 2.0
Chris@0 33 *
Chris@0 34 * @deprecated the ClassLoader is deprecated and will be removed in version 3.0 of doctrine/common.
Chris@0 35 */
Chris@0 36 class ClassLoader
Chris@0 37 {
Chris@0 38 /**
Chris@0 39 * PHP file extension.
Chris@0 40 *
Chris@0 41 * @var string
Chris@0 42 */
Chris@0 43 protected $fileExtension = '.php';
Chris@0 44
Chris@0 45 /**
Chris@0 46 * Current namespace.
Chris@0 47 *
Chris@0 48 * @var string|null
Chris@0 49 */
Chris@0 50 protected $namespace;
Chris@0 51
Chris@0 52 /**
Chris@0 53 * Current include path.
Chris@0 54 *
Chris@0 55 * @var string|null
Chris@0 56 */
Chris@0 57 protected $includePath;
Chris@0 58
Chris@0 59 /**
Chris@0 60 * PHP namespace separator.
Chris@0 61 *
Chris@0 62 * @var string
Chris@0 63 */
Chris@0 64 protected $namespaceSeparator = '\\';
Chris@0 65
Chris@0 66 /**
Chris@0 67 * Creates a new <tt>ClassLoader</tt> that loads classes of the
Chris@0 68 * specified namespace from the specified include path.
Chris@0 69 *
Chris@0 70 * If no include path is given, the ClassLoader relies on the PHP include_path.
Chris@0 71 * If neither a namespace nor an include path is given, the ClassLoader will
Chris@0 72 * be responsible for loading all classes, thereby relying on the PHP include_path.
Chris@0 73 *
Chris@0 74 * @param string|null $ns The namespace of the classes to load.
Chris@0 75 * @param string|null $includePath The base include path to use.
Chris@0 76 */
Chris@0 77 public function __construct($ns = null, $includePath = null)
Chris@0 78 {
Chris@0 79 $this->namespace = $ns;
Chris@0 80 $this->includePath = $includePath;
Chris@0 81 }
Chris@0 82
Chris@0 83 /**
Chris@0 84 * Sets the namespace separator used by classes in the namespace of this ClassLoader.
Chris@0 85 *
Chris@0 86 * @param string $sep The separator to use.
Chris@0 87 *
Chris@0 88 * @return void
Chris@0 89 */
Chris@0 90 public function setNamespaceSeparator($sep)
Chris@0 91 {
Chris@0 92 $this->namespaceSeparator = $sep;
Chris@0 93 }
Chris@0 94
Chris@0 95 /**
Chris@0 96 * Gets the namespace separator used by classes in the namespace of this ClassLoader.
Chris@0 97 *
Chris@0 98 * @return string
Chris@0 99 */
Chris@0 100 public function getNamespaceSeparator()
Chris@0 101 {
Chris@0 102 return $this->namespaceSeparator;
Chris@0 103 }
Chris@0 104
Chris@0 105 /**
Chris@0 106 * Sets the base include path for all class files in the namespace of this ClassLoader.
Chris@0 107 *
Chris@0 108 * @param string|null $includePath
Chris@0 109 *
Chris@0 110 * @return void
Chris@0 111 */
Chris@0 112 public function setIncludePath($includePath)
Chris@0 113 {
Chris@0 114 $this->includePath = $includePath;
Chris@0 115 }
Chris@0 116
Chris@0 117 /**
Chris@0 118 * Gets the base include path for all class files in the namespace of this ClassLoader.
Chris@0 119 *
Chris@0 120 * @return string|null
Chris@0 121 */
Chris@0 122 public function getIncludePath()
Chris@0 123 {
Chris@0 124 return $this->includePath;
Chris@0 125 }
Chris@0 126
Chris@0 127 /**
Chris@0 128 * Sets the file extension of class files in the namespace of this ClassLoader.
Chris@0 129 *
Chris@0 130 * @param string $fileExtension
Chris@0 131 *
Chris@0 132 * @return void
Chris@0 133 */
Chris@0 134 public function setFileExtension($fileExtension)
Chris@0 135 {
Chris@0 136 $this->fileExtension = $fileExtension;
Chris@0 137 }
Chris@0 138
Chris@0 139 /**
Chris@0 140 * Gets the file extension of class files in the namespace of this ClassLoader.
Chris@0 141 *
Chris@0 142 * @return string
Chris@0 143 */
Chris@0 144 public function getFileExtension()
Chris@0 145 {
Chris@0 146 return $this->fileExtension;
Chris@0 147 }
Chris@0 148
Chris@0 149 /**
Chris@0 150 * Registers this ClassLoader on the SPL autoload stack.
Chris@0 151 *
Chris@0 152 * @return void
Chris@0 153 */
Chris@0 154 public function register()
Chris@0 155 {
Chris@0 156 spl_autoload_register([$this, 'loadClass']);
Chris@0 157 }
Chris@0 158
Chris@0 159 /**
Chris@0 160 * Removes this ClassLoader from the SPL autoload stack.
Chris@0 161 *
Chris@0 162 * @return void
Chris@0 163 */
Chris@0 164 public function unregister()
Chris@0 165 {
Chris@0 166 spl_autoload_unregister([$this, 'loadClass']);
Chris@0 167 }
Chris@0 168
Chris@0 169 /**
Chris@0 170 * Loads the given class or interface.
Chris@0 171 *
Chris@0 172 * @param string $className The name of the class to load.
Chris@0 173 *
Chris@0 174 * @return boolean TRUE if the class has been successfully loaded, FALSE otherwise.
Chris@0 175 */
Chris@0 176 public function loadClass($className)
Chris@0 177 {
Chris@0 178 if (self::typeExists($className)) {
Chris@0 179 return true;
Chris@0 180 }
Chris@0 181
Chris@0 182 if (! $this->canLoadClass($className)) {
Chris@0 183 return false;
Chris@0 184 }
Chris@0 185
Chris@0 186 require ($this->includePath !== null ? $this->includePath . DIRECTORY_SEPARATOR : '')
Chris@0 187 . str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className)
Chris@0 188 . $this->fileExtension;
Chris@0 189
Chris@0 190 return self::typeExists($className);
Chris@0 191 }
Chris@0 192
Chris@0 193 /**
Chris@0 194 * Asks this ClassLoader whether it can potentially load the class (file) with
Chris@0 195 * the given name.
Chris@0 196 *
Chris@0 197 * @param string $className The fully-qualified name of the class.
Chris@0 198 *
Chris@0 199 * @return boolean TRUE if this ClassLoader can load the class, FALSE otherwise.
Chris@0 200 */
Chris@0 201 public function canLoadClass($className)
Chris@0 202 {
Chris@0 203 if ($this->namespace !== null && strpos($className, $this->namespace.$this->namespaceSeparator) !== 0) {
Chris@0 204 return false;
Chris@0 205 }
Chris@0 206
Chris@0 207 $file = str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className) . $this->fileExtension;
Chris@0 208
Chris@0 209 if ($this->includePath !== null) {
Chris@0 210 return is_file($this->includePath . DIRECTORY_SEPARATOR . $file);
Chris@0 211 }
Chris@0 212
Chris@0 213 return (false !== stream_resolve_include_path($file));
Chris@0 214 }
Chris@0 215
Chris@0 216 /**
Chris@0 217 * Checks whether a class with a given name exists. A class "exists" if it is either
Chris@0 218 * already defined in the current request or if there is an autoloader on the SPL
Chris@0 219 * autoload stack that is a) responsible for the class in question and b) is able to
Chris@0 220 * load a class file in which the class definition resides.
Chris@0 221 *
Chris@0 222 * If the class is not already defined, each autoloader in the SPL autoload stack
Chris@0 223 * is asked whether it is able to tell if the class exists. If the autoloader is
Chris@0 224 * a <tt>ClassLoader</tt>, {@link canLoadClass} is used, otherwise the autoload
Chris@0 225 * function of the autoloader is invoked and expected to return a value that
Chris@0 226 * evaluates to TRUE if the class (file) exists. As soon as one autoloader reports
Chris@0 227 * that the class exists, TRUE is returned.
Chris@0 228 *
Chris@0 229 * Note that, depending on what kinds of autoloaders are installed on the SPL
Chris@0 230 * autoload stack, the class (file) might already be loaded as a result of checking
Chris@0 231 * for its existence. This is not the case with a <tt>ClassLoader</tt>, who separates
Chris@0 232 * these responsibilities.
Chris@0 233 *
Chris@0 234 * @param string $className The fully-qualified name of the class.
Chris@0 235 *
Chris@0 236 * @return boolean TRUE if the class exists as per the definition given above, FALSE otherwise.
Chris@0 237 */
Chris@0 238 public static function classExists($className)
Chris@0 239 {
Chris@0 240 return self::typeExists($className, true);
Chris@0 241 }
Chris@0 242
Chris@0 243 /**
Chris@0 244 * Gets the <tt>ClassLoader</tt> from the SPL autoload stack that is responsible
Chris@0 245 * for (and is able to load) the class with the given name.
Chris@0 246 *
Chris@0 247 * @param string $className The name of the class.
Chris@0 248 *
Chris@0 249 * @return ClassLoader The <tt>ClassLoader</tt> for the class or NULL if no such <tt>ClassLoader</tt> exists.
Chris@0 250 */
Chris@0 251 public static function getClassLoader($className)
Chris@0 252 {
Chris@0 253 foreach (spl_autoload_functions() as $loader) {
Chris@0 254 if (is_array($loader)
Chris@0 255 && ($classLoader = reset($loader))
Chris@0 256 && $classLoader instanceof ClassLoader
Chris@0 257 && $classLoader->canLoadClass($className)
Chris@0 258 ) {
Chris@0 259 return $classLoader;
Chris@0 260 }
Chris@0 261 }
Chris@0 262
Chris@0 263 return null;
Chris@0 264 }
Chris@0 265
Chris@0 266 /**
Chris@0 267 * Checks whether a given type exists
Chris@0 268 *
Chris@0 269 * @param string $type
Chris@0 270 * @param bool $autoload
Chris@0 271 *
Chris@0 272 * @return bool
Chris@0 273 */
Chris@0 274 private static function typeExists($type, $autoload = false)
Chris@0 275 {
Chris@0 276 return class_exists($type, $autoload)
Chris@0 277 || interface_exists($type, $autoload)
Chris@0 278 || trait_exists($type, $autoload);
Chris@0 279 }
Chris@0 280 }