zend_loader_autoloader 源码 分析
来源:互联网 发布:推理题目的软件 编辑:程序博客网 时间:2024/05/19 00:51
<?phprequire_once 'Zend/Loader.php';//这个类的作用是注册自动加载方法,而且可以为各个命名空间注册方法class Zend_Loader_Autoloader{ //单例变量 protected static $_instance;
//所有的自动加载方法集合 protected $_autoloaders = array();
//默认自动加载方法,用zend自带的类 protected $_defaultAutoloader = array('Zend_Loader', 'loadClass');
//是否会有一个可靠的自动加载类 protected $_fallbackAutoloader = false;
//核 心自动加载方法 protected $_internalAutoloader;
//命名空间集合 protected $_namespaces = array( 'Zend_' => true, 'ZendX_' => true, );
/** * 示例: array('zend'=>array(array('zend_loader', 'autoload'), array('zend_load_autoloader', 'autoload'), 'zendx'=>array()); */ protected $_namespaceAutoloaders = array();
//是否屏蔽错误 protected $_suppressNotFoundWarnings = false;
//zend框架的路径 protected $_zfPath;
//经典单例模式 public static function getInstance() { if (null === self::$_instance) { self::$_instance = new self(); } return self::$_instance; }
//释放单例 public static function resetInstance() { self::$_instance = null; }
//被注册的自动加载方法,根据命 名空间找出对应的自动加载方法,然后加载类,加载成功返回真,否则false public static function autoload($class) { $self = self::getInstance();
foreach ($self->getClassAutoloaders($class) as $autoloader) { //从这里可以看出,自定义的自动加载方法支持三种形式1, 继承自zend内部接口类,2, 自定义的类, 3, 自定义的方法 if ($autoloader instanceof Zend_Loader_Autoloader_Interface) { if ($autoloader->autoload($class)) { return true; } } elseif (is_array($autoloader)) { if (call_user_func($autoloader, $class)) { return true; } } elseif (is_string($autoloader) || is_callable($autoloader)) { if ($autoloader($class)) { return true; } } }
return false; }
//为默认自动加载属性赋值 public function setDefaultAutoloader($callback) { if (!is_callable($callback)) { throw new Zend_Loader_Exception('Invalid callback specified for default autoloader'); }
$this->_defaultAutoloader = $callback; return $this; }
public function getDefaultAutoloader()//默认加载方法的getter方法 { return $this->_defaultAutoloader; }
/** * Set several autoloader callbacks at once * * @param array $autoloaders Array of PHP callbacks (or Zend_Loader_Autoloader_Interface implementations) to act as autoloaders * @return Zend_Loader_Autoloader */ public function setAutoloaders(array $autoloaders) { $this->_autoloaders = $autoloaders; return $this; }
/** * Get attached autoloader implementations * * @return array */ public function getAutoloaders() { return $this->_autoloaders; }
//根扰命名空间返回相应的自动加载方法 public function getNamespaceAutoloaders($namespace) { $namespace = (string) $namespace; if (!array_key_exists($namespace, $this->_namespaceAutoloaders)) { return array(); } return $this->_namespaceAutoloaders[$namespace]; }
//注册命名空间,字串或数组 public function registerNamespace($namespace) { if (is_string($namespace)) { $namespace = (array) $namespace; } elseif (!is_array($namespace)) { throw new Zend_Loader_Exception('Invalid namespace provided'); }
foreach ($namespace as $ns) { if (!isset($this->_namespaces[$ns])) { $this->_namespaces[$ns] = true; } } return $this; }
//注销一个命名空间, 遍历数组并unset public function unregisterNamespace($namespace) { if (is_string($namespace)) { $namespace = (array) $namespace; } elseif (!is_array($namespace)) { throw new Zend_Loader_Exception('Invalid namespace provided'); }
foreach ($namespace as $ns) { if (isset($this->_namespaces[$ns])) { unset($this->_namespaces[$ns]); } } return $this; }
//取得所有注册的命名空间 public function getRegisteredNamespaces() { return array_keys($this->_namespaces); } //设置不同版本的zend目录 public function setZfPath($spec, $version = 'latest') { $path = $spec; if (is_array($spec)) { if (!isset($spec['path'])) { throw new Zend_Loader_Exception('No path specified for ZF'); } $path = $spec['path']; if (isset($spec['version'])) { $version = $spec['version']; } }
$this->_zfPath = $this->_getVersionPath($path, $version); set_include_path(implode(PATH_SEPARATOR, array( $this->_zfPath, get_include_path(), ))); return $this; }
public function getZfPath() { return $this->_zfPath; }
//设置或取得支持屏蔽错误这个属性 public function suppressNotFoundWarnings($flag = null) { if (null === $flag) { return $this->_suppressNotFoundWarnings; } $this->_suppressNotFoundWarnings = (bool) $flag; return $this; }
//设置支持可靠自动加载属性 public function setFallbackAutoloader($flag) { $this->_fallbackAutoloader = (bool) $flag; return $this; }
//取得可靠自动加载属性 public function isFallbackAutoloader() { return $this->_fallbackAutoloader; }
//根据类名取得本类的自动加载方法 public function getClassAutoloaders($class) { $namespace = false; $autoloaders = array();
//根据类名,取得所有注册的 命名空间=>自动加载方法 对,如果有本类名的命名空间,则生成确定命名空间和自动加载方法 foreach (array_keys($this->_namespaceAutoloaders) as $ns) { if ('' == $ns) { continue; } if (0 === strpos($class, $ns)) { if ((false === $namespace) || (strlen($ns) > strlen($namespace))) { $namespace = $ns; $autoloaders = $this->getNamespaceAutoloaders($ns); } } }
//取得所有注册的命名空间,如果上述命名空间在内,则将核心自动加载方法写入自动加载列表 foreach ($this->getRegisteredNamespaces() as $ns) { if (0 === strpos($class, $ns)) { $namespace = $ns; $autoloaders[] = $this->_internalAutoloader; break; } }
//如果没有命名空间则加载无命 名空间的自动加载方法 $autoloadersNonNamespace = $this->getNamespaceAutoloaders('');//php支持key为''的数组 if (count($autoloadersNonNamespace)) { foreach ($autoloadersNonNamespace as $ns) { $autoloaders[] = $ns; } unset($autoloadersNonNamespace); }
//如果命名空间不存在,并且可靠自动加载为真,则自动加载方法是核心加载方法 if (!$namespace && $this->isFallbackAutoloader()) { $autoloaders[] = $this->_internalAutoloader; }
return $autoloaders; }
//向栈的头部插入自动加载方法,并指定命名空间,并修改自动加载方法合集_autoloaders public function unshiftAutoloader($callback, $namespace = '') { $autoloaders = $this->getAutoloaders(); array_unshift($autoloaders, $callback); $this->setAutoloaders($autoloaders);
$namespace = (array) $namespace; foreach ($namespace as $ns) { $autoloaders = $this->getNamespaceAutoloaders($ns); array_unshift($autoloaders, $callback); $this->_setNamespaceAutoloaders($autoloaders, $ns); }
return $this; }
//为指定命名空间指定自动加载方法,并且记录到_autoloaders属性里 public function pushAutoloader($callback, $namespace = '') { $autoloaders = $this->getAutoloaders(); array_push($autoloaders, $callback); $this->setAutoloaders($autoloaders);
$namespace = (array) $namespace; foreach ($namespace as $ns) { $autoloaders = $this->getNamespaceAutoloaders($ns); array_push($autoloaders, $callback); $this->_setNamespaceAutoloaders($autoloaders, $ns); }
return $this; }
//删除自动加载方法 public function removeAutoloader($callback, $namespace = null) { if (null === $namespace) {//无命名空间则全部删除 $autoloaders = $this->getAutoloaders(); if (false !== ($index = array_search($callback, $autoloaders, true))) { unset($autoloaders[$index]); $this->setAutoloaders($autoloaders); }
foreach ($this->_namespaceAutoloaders as $ns => $autoloaders) { if (false !== ($index = array_search($callback, $autoloaders, true))) { unset($autoloaders[$index]); $this->_setNamespaceAutoloaders($autoloaders, $ns); } } } else {//有命名空间则只删命名空间下的 $namespace = (array) $namespace; foreach ($namespace as $ns) { $autoloaders = $this->getNamespaceAutoloaders($ns); if (false !== ($index = array_search($callback, $autoloaders, true))) { unset($autoloaders[$index]); $this->_setNamespaceAutoloaders($autoloaders, $ns); } } }
return $this; }
protected function __construct() { spl_autoload_register(array(__CLASS__, 'autoload'));//注册自动加载方法 $this->_internalAutoloader = array($this, '_autoload');//为核心自动加载方法赋值 }
protected function _autoload($class)//核心自动加载方法,内部有是否报错开关,可屏蔽警告错误,成功返回类名,失败返回false { $callback = $this->getDefaultAutoloader(); try { if ($this->suppressNotFoundWarnings()) { @call_user_func($callback, $class); } else { call_user_func($callback, $class); } return $class; } catch (Zend_Exception $e) { return false; } }
//设置某命名空间的自动加载方法 protected function _setNamespaceAutoloaders(array $autoloaders, $namespace = '') { $namespace = (string) $namespace; $this->_namespaceAutoloaders[$namespace] = $autoloaders; return $this; }
//根据版本找出路径 protected function _getVersionPath($path, $version) { $type = $this->_getVersionType($version);
if ($type == 'latest') { $version = 'latest'; }
$availableVersions = $this->_getAvailableVersions($path, $version); if (empty($availableVersions)) { throw new Zend_Loader_Exception('No valid ZF installations discovered'); }
$matchedVersion = array_pop($availableVersions); return $matchedVersion; }
//返回最多4种版本,latest=>latest, 1=>major, 1.1=>minor, 1.1.1=>specific, 1.1.1.1.1=>error protected function _getVersionType($version) { if (strtolower($version) == 'latest') { return 'latest'; }
$parts = explode('.', $version); $count = count($parts); if (1 == $count) { return 'major'; } if (2 == $count) { return 'minor'; } if (3 < $count) { throw new Zend_Loader_Exception('Invalid version string provided'); } return 'specific'; }
//根据版本返回对应的zend库目录 protected function _getAvailableVersions($path, $version) { if (!is_dir($path)) { throw new Zend_Loader_Exception('Invalid ZF path provided'); }
$path = rtrim($path, '/'); $path = rtrim($path, '\\'); $versionLen = strlen($version); $versions = array(); $dirs = glob("$path/*", GLOB_ONLYDIR);//返回与模式匹配的目录数组 foreach ((array) $dirs as $dir) { $dirName = substr($dir, strlen($path) + 1); if (!preg_match('/^(?:ZendFramework-)?(\d+\.\d+\.\d+((a|b|pl|pr|p|rc)\d+)?)(?:-minimal)?$/i', $dirName, $matches)) { continue; }
$matchedVersion = $matches[1];//匹配出zend的版本
if (('latest' == $version) || ((strlen($matchedVersion) >= $versionLen) && (0 === strpos($matchedVersion, $version))) ) { $versions[$matchedVersion] = $dir . '/library';//找出zend库的目录 } }
uksort($versions, 'version_compare');//对版本进行排序 return $versions; }}
- zend_loader_autoloader 源码 分析
- Zend Framework 1.8 Zend_Loader_Autoloader 原理分析.
- Zend_Loader_Autoloader的运行原理
- zend framework 1.10升级使用Zend_Loader_Autoloader
- Zend Framwork Zend_Loader_Autoloader 配置多模块
- 源码分析
- 源码分析
- 源码分析
- 源码分析
- 源码分析
- 源码分析
- 源码分析
- 源码分析
- 源码分析:SparseArray分析
- 源码- Spark Broadcast源码分析
- Android源码/框架源码分析
- 【Android应用源码分析】HandlerThread 源码分析
- 【Android应用源码分析】IntentService 源码分析
- JAVA 正则表达式
- Supercell谈《Clash of Clans》起源及发展计划
- 关于公司的SVN服务器的一些小事
- 第十一周任务2—穷举法算元化分
- 使用python logging处理多机多进程写同一个日志文件
- zend_loader_autoloader 源码 分析
- 普通应用程序转化成服务程序+服务程序相对路径切换
- 百鸡百钱
- 互联网第二轮泡沫之辩:是享受还是逃离 (2)
- opencv 金字塔图像分割
- JS逗号运算符的用法详解
- 百钱买百鸡(第十一周上机任务)
- “张三,李四,王五,刘六”的年龄几何
- 当前时间(阴历,阳历)