File indexing completed on 2024-12-22 05:36:49
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Loader 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 */ 0020 0021 // require_once dirname(__FILE__) . '/SplAutoloader.php'; 0022 0023 if (class_exists('Zend_Loader_AutoloaderFactory')) return; 0024 0025 /** 0026 * @package Zend_Loader 0027 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0028 * @license http://framework.zend.com/license/new-bsd New BSD License 0029 */ 0030 abstract class Zend_Loader_AutoloaderFactory 0031 { 0032 const STANDARD_AUTOLOADER = 'Zend_Loader_StandardAutoloader'; 0033 const CLASS_MAP_AUTOLOADER = 'Zend_Loader_ClassMapAutoloader'; 0034 0035 /** 0036 * @var array All autoloaders registered using the factory 0037 */ 0038 protected static $loaders = array(); 0039 0040 /** 0041 * @var Zend_Loader_StandardAutoloader StandardAutoloader instance for resolving 0042 * autoloader classes via the include_path 0043 */ 0044 protected static $standardAutoloader; 0045 0046 /** 0047 * Factory for autoloaders 0048 * 0049 * Options should be an array or Traversable object of the following structure: 0050 * <code> 0051 * array( 0052 * '<autoloader class name>' => $autoloaderOptions, 0053 * ) 0054 * </code> 0055 * 0056 * The factory will then loop through and instantiate each autoloader with 0057 * the specified options, and register each with the spl_autoloader. 0058 * 0059 * You may retrieve the concrete autoloader instances later using 0060 * {@link getRegisteredAutoloaders()}. 0061 * 0062 * Note that the class names must be resolvable on the include_path or via 0063 * the Zend library, using PSR-0 rules (unless the class has already been 0064 * loaded). 0065 * 0066 * @param array|Traversable $options (optional) options to use. Defaults to Zend_Loader_StandardAutoloader 0067 * @return void 0068 * @throws Zend_Loader_Exception_InvalidArgumentException for invalid options 0069 * @throws Zend_Loader_Exception_InvalidArgumentException for unloadable autoloader classes 0070 */ 0071 public static function factory($options = null) 0072 { 0073 if (null === $options) { 0074 if (!isset(self::$loaders[self::STANDARD_AUTOLOADER])) { 0075 $autoloader = self::getStandardAutoloader(); 0076 $autoloader->register(); 0077 self::$loaders[self::STANDARD_AUTOLOADER] = $autoloader; 0078 } 0079 0080 // Return so we don't hit the next check's exception (we're done here anyway) 0081 return; 0082 } 0083 0084 if (!is_array($options) && !($options instanceof Traversable)) { 0085 // require_once 'Exception/InvalidArgumentException.php'; 0086 throw new Zend_Loader_Exception_InvalidArgumentException( 0087 'Options provided must be an array or Traversable' 0088 ); 0089 } 0090 0091 foreach ($options as $class => $options) { 0092 if (!isset(self::$loaders[$class])) { 0093 // Check class map autoloader 0094 if ($class == self::CLASS_MAP_AUTOLOADER) { 0095 if (!class_exists(self::CLASS_MAP_AUTOLOADER)) { 0096 // Extract the filename from the classname 0097 $classMapLoader = substr( 0098 strrchr(self::CLASS_MAP_AUTOLOADER, '_'), 1 0099 ); 0100 0101 // require_once dirname(__FILE__) . "/$classMapLoader.php"; 0102 } 0103 } 0104 0105 // Autoload with standard autoloader 0106 $autoloader = self::getStandardAutoloader(); 0107 if (!class_exists($class) && !$autoloader->autoload($class)) { 0108 // require_once 'Exception/InvalidArgumentException.php'; 0109 throw new Zend_Loader_Exception_InvalidArgumentException(sprintf( 0110 'Autoloader class "%s" not loaded', 0111 $class 0112 )); 0113 } 0114 0115 // unfortunately is_subclass_of is broken on some 5.3 versions 0116 // additionally instanceof is also broken for this use case 0117 if (version_compare(PHP_VERSION, '5.3.7', '>=')) { 0118 if (!is_subclass_of($class, 'Zend_Loader_SplAutoloader')) { 0119 // require_once 'Exception/InvalidArgumentException.php'; 0120 throw new Zend_Loader_Exception_InvalidArgumentException(sprintf( 0121 'Autoloader class %s must implement Zend\\Loader\\SplAutoloader', 0122 $class 0123 )); 0124 } 0125 } 0126 0127 if ($class === self::STANDARD_AUTOLOADER) { 0128 $autoloader->setOptions($options); 0129 } else { 0130 $autoloader = new $class($options); 0131 } 0132 $autoloader->register(); 0133 self::$loaders[$class] = $autoloader; 0134 } else { 0135 self::$loaders[$class]->setOptions($options); 0136 } 0137 } 0138 } 0139 0140 /** 0141 * Get an list of all autoloaders registered with the factory 0142 * 0143 * Returns an array of autoloader instances. 0144 * 0145 * @return array 0146 */ 0147 public static function getRegisteredAutoloaders() 0148 { 0149 return self::$loaders; 0150 } 0151 0152 /** 0153 * Retrieves an autoloader by class name 0154 * 0155 * @param string $class 0156 * @return Zend_Loader_SplAutoloader 0157 * @throws Zend_Loader_Exception_InvalidArgumentException for non-registered class 0158 */ 0159 public static function getRegisteredAutoloader($class) 0160 { 0161 if (!isset(self::$loaders[$class])) { 0162 // require_once 'Exception/InvalidArgumentException.php'; 0163 throw new Zend_Loader_Exception_InvalidArgumentException(sprintf('Autoloader class "%s" not loaded', $class)); 0164 } 0165 return self::$loaders[$class]; 0166 } 0167 0168 /** 0169 * Unregisters all autoloaders that have been registered via the factory. 0170 * This will NOT unregister autoloaders registered outside of the fctory. 0171 * 0172 * @return void 0173 */ 0174 public static function unregisterAutoloaders() 0175 { 0176 foreach (self::getRegisteredAutoloaders() as $class => $autoloader) { 0177 spl_autoload_unregister(array($autoloader, 'autoload')); 0178 unset(self::$loaders[$class]); 0179 } 0180 } 0181 0182 /** 0183 * Unregister a single autoloader by class name 0184 * 0185 * @param string $autoloaderClass 0186 * @return bool 0187 */ 0188 public static function unregisterAutoloader($autoloaderClass) 0189 { 0190 if (!isset(self::$loaders[$autoloaderClass])) { 0191 return false; 0192 } 0193 0194 $autoloader = self::$loaders[$autoloaderClass]; 0195 spl_autoload_unregister(array($autoloader, 'autoload')); 0196 unset(self::$loaders[$autoloaderClass]); 0197 return true; 0198 } 0199 0200 /** 0201 * Get an instance of the standard autoloader 0202 * 0203 * Used to attempt to resolve autoloader classes, using the 0204 * StandardAutoloader. The instance is marked as a fallback autoloader, to 0205 * allow resolving autoloaders not under the "Zend" or "Zend" namespaces. 0206 * 0207 * @return Zend_Loader_SplAutoloader 0208 */ 0209 protected static function getStandardAutoloader() 0210 { 0211 if (null !== self::$standardAutoloader) { 0212 return self::$standardAutoloader; 0213 } 0214 0215 // Extract the filename from the classname 0216 $stdAutoloader = substr(strrchr(self::STANDARD_AUTOLOADER, '_'), 1); 0217 0218 if (!class_exists(self::STANDARD_AUTOLOADER)) { 0219 // require_once dirname(__FILE__) . "/$stdAutoloader.php"; 0220 } 0221 $loader = new Zend_Loader_StandardAutoloader(); 0222 self::$standardAutoloader = $loader; 0223 return self::$standardAutoloader; 0224 } 0225 }