现在的位置: 首页 > 综合 > 正文

Zend_Loader类结构及功能分析

2012年06月13日 ⁄ 综合 ⁄ 共 3637字 ⁄ 字号 评论关闭

Zend_Loader类结构及功能分析 

 

    Zend_Loader用于动态加载类和文件,该类的方法全部为静态类型,类结构如下:

 

 

 关于Zend_Loader 与 require_once()

Zend_Loader 主要用于通过动态请求的映射的变量标识的文件名来加载的文件(例如你要加载的文件的名称来自于用户的输入或者某个方法的参数),有程序托管加载对应的文件。

若只是加载确定的文件或类(即确定的文件或类,如/lib/test.php),则使用 传统的PHP函数 require_once()或include_once()更合适,使用Zend_Loader就多余的浪费了。

 

该类有4个核心功能分别为:

1、加载文件 Zend_Loader::loadFile($filename)

该方法用于加载PHP文件,实际上是对include()或include_once()的封装,并添加了文件名安全性检查。

public static function loadFile($filename$dirs = null$once = false)

参数说明:

    $filename 参数指定需要加载的文件,$filename必须是包含扩展名(例如:".php")的完整文件名,但不需要指定任何路径。

然后会对文件名做安全性检查,文件名只能由字母,数字,连接符(-),下划线(_)及英文半角句号(.)组成。$dirs参数则不限。

     $dirs 可以是一个目录字符串也可以是目录数组,默认是null,该方法会按照目录参数提供的顺序在指定的目录中查找指定的文件,并尝试加载第一次匹配到的文件。

如果在指定的$dirs中未找到文件,或者没有专门制定该参数,则该方法将尝试从PHP的 include_path中加载文件。实际上该方法是把制定的$dirs以

PATH_SEPARATOR连接成字符串追加到include_path的最前端,然后include或include_once来加载文件的。

     $once 可选参数用于指定是否是一次性加载,即如果为true则使用include_once加载文件,否则(默认)使用include加载文件。

2、加载类 Zend_Loader::loadClass($class, $dirs)

从PHP文件中load一个Class,文件名必须是$class.php 格式的,加载文件后判断类是否存在。

publicstaticfunction loadClass($class$dirs = null)

参数说明 :

      $class 类名,其对应类所在文件的文件名必须是$class.php格式。

      $dirs 要搜索的目录,可以是目录字符串或者目录字符串组成的数组,默认是null;

    该方法将按照$dirs提供的顺序查找对应的类文件,第一个匹配到的文件将被加载。如果在指定的dirs中不存在该类文件,

    或者没有特别指明$dirs则从PHP环境include_path中查找。若文件不存在或者加载文件后不存在该类则throw异常。

方法作用:

1)、首先判定指定的类或接口是否存在,存在则直接return,否则判定指定的$dirs是否合法,即是否是null或字符串或者数组,否则throw异常。

2)、然后类名字符串"$class"将根据操作系统OS,通过把其中的下划线(_)替换成对应的目录分隔符而转换为相对路径。

      例如:下面的例子,在指定的目录中查找并加载类Container_Tree,类名将被映射为这样的路径层级结构:"Container/Tree.php" ,

      windows系统中则为"Container\\Tree.php".

      

3)、因为从PHP5.3开始PHP本身引入了namespace的概念,并且从zendFramework1.10开始,支持从用户自定义的PHP名称空间(namespace)中加载类。

      ZF从PHP的namespace中加载类遵循如下的三个规则:

      a)、从文件系统中加载时namespace的分隔符("\")被转换成目录分隔符DIRECTORY_SEPARATOR ("\"或"/")。

      b)、类文件名中的下划线"_"将被转换成目录分隔符DIRECTORY_SEPARATOR ("\"或"/")。下划线"_"在PHP的namespace中没有特殊的意义。

      c)、从文件系统中加载时 完整的名称空间和类是带有后缀".php"的。

      例如下面的映射关系:

\Doctrine\Common\IsolatedClassLoader =>/path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php 

\namespace\package\Class_Name =>/path/to/project/lib/vendor/namespace/package/Class/Name.php 

\namespace\package_name\Class_Name =>/path/to/project/lib/vendor/namespace/package_name/Class/Name.php 

      所以在上一步转换类名为相对路径是需要先用namespace分隔符分离名称空间和类名,然后再按以上三条规则转换为相对路径。

4)、将指定的$dir并上类名$class中转换出的相对路径作为目录,调用self::loadFile($file, $dirs, true);完成文件加载

5)、最后判定类class是否存在,否则throw异常。 

3、判定指定的文件是否存在且可读性 Zend_Loader::isReadable($pathname)

  静态方法Zend_Loader::isReadable($pathname)判定某个文件是否存在并可读,可读则返回 TRUE ,否则返回 FALSE。

 

if (Zend_Loader::isReadable($filename)) {
     // do something with $filename
}

 

$filename参数指定了要检查的文件名,包括路径信息。这个方法是将 PHP 函数is_readable()封装而成的。

is_readable() 不会自动查找 include_path 下的文件,而 Zend::isReadable() 可以。

4、注册并使用Autoloader功能。 

                        Zend_Loader的autoloadregisterAutoload方法从1.8版本开始废弃使用,而且将在ZF2.0版本中移除这两个方法。

                        1)、Zend_Loader::autoload($class)方法只是对Zend_Loader::loadClass($class)的引用和封装而已,ZF1.11版本中不再

                            使用该方法做为自动加载器方法,而是将Zend_Loader_Autoloader::autoload($class)方法作为默认自动加载器方法。

                        2)、Zend_Loader::registerAutoload($class = 'Zend_Loader', $enabled = true),

                                    该方法首先将Zend_Loader_Autoloader设置为后备加载器,见代码:

                  require_once 'Zend/Loader/Autoloader.php';
                  $autoloader = Zend_Loader_Autoloader::getInstance();
                  $autoloader->setFallbackAutoloader(true);

                              设置后备加载器其意义在于:在加载类的时候,若无该类对应的名称空间加载器且也无非名称空间的加载器时,将使用Zend_ Loader_Autoloader的

                              内部自动加载器_internalAutoloader = array($this, '_autoload');而_autoload方法实际上就是使用Zend_Loader::loadClass方法。

  然后若要注册的加载器不是Zend_Loader则注册为自动加载器,放入autoloaders堆栈和namespaceAutoloaders堆栈中。

 

 

抱歉!评论已关闭.