侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Zend Framework教程之Loader以及PluginLoader用法详解

框架(架构)  /  管理员 发布于 7年前   118

本文实例分析了Zend Framework中Loader以及PluginLoader用法。分享给大家供大家参考,具体如下:

Zend Framework提供了Zend_Loader,用来动态加载文件。

以下是具体用法,以及具体实现:

1.加载文件

使用方法:

Zend_Loader::loadFile($filename, $dirs=null, $once=false);

具体实现:

/** * Loads a PHP file. This is a wrapper for PHP's include() function. * * $filename must be the complete filename, including any * extension such as ".php". Note that a security check is performed that * does not permit extended characters in the filename. This method is * intended for loading Zend Framework files. * * If $dirs is a string or an array, it will search the directories * in the order supplied, and attempt to load the first matching file. * * If the file was not found in the $dirs, or if no $dirs were specified, * it will attempt to load it from PHP's include_path. * * If $once is TRUE, it will use include_once() instead of include(). * * @param string    $filename * @param string|array $dirs - OPTIONAL either a path or array of paths *to search. * @param boolean    $once * @return boolean * @throws Zend_Exception */public static function loadFile($filename, $dirs = null, $once = false){  self::_securityCheck($filename);  /**   * Search in provided directories, as well as include_path   */  $incPath = false;  if (!empty($dirs) && (is_array($dirs) || is_string($dirs))) {    if (is_array($dirs)) {      $dirs = implode(PATH_SEPARATOR, $dirs);    }    $incPath = get_include_path();    set_include_path($dirs . PATH_SEPARATOR . $incPath);  }  /**   * Try finding for the plain filename in the include_path.   */  if ($once) {    include_once $filename;  } else {    include $filename;  }  /**   * If searching in directories, reset include_path   */  if ($incPath) {    set_include_path($incPath);  }  return true;}

参数规则:

正如实现方法,有如下参数

$filename参数指定需要加载的文件,注意$filename不需要指定任何路径,只需要文件名即可。ZF会对文件作安全性检查。$filename 只能由字母,数字,连接符-,下划线_及英文句号.组成(半角)。$dirs参数则不限,可以使用中文等。

$dirs 参数用来指定文件所在目录,可以是一个字符串或者数组。如果为 NULL,则程序将会到系统的 include_path 下寻找文件是否存在(include_path可在php.ini中设置--Haohappy注),如果是字符串或数组,则会到指定的目录下去找,然后才是 include_path。

$once 参数为布尔类型,如果为 TRUE,Zend_Loader::loadFile() 使用 PHP 函数 » include_once() 加载文件,否则就是 PHP 函数 » include()。(本参数只能是true或false,两者区别就和include()和include_once()的区别一样。)

2.加载类

具体使用:

Zend_Loader::loadClass('Container_Tree',  array(    '/home/production/mylib',    '/home/production/myapp'  ));

具体实现:

/*** Loads a class from a PHP file. The filename must be formatted* as "$class.php".** If $dirs is a string or an array, it will search the directories* in the order supplied, and attempt to load the first matching file.** If $dirs is null, it will split the class name at underscores to* generate a path hierarchy (e.g., "Zend_Example_Class" will map* to "Zend/Example/Class.php").** If the file was not found in the $dirs, or if no $dirs were specified,* it will attempt to load it from PHP's include_path.** @param string $class   - The full class name of a Zend component.* @param string|array $dirs - OPTIONAL Either a path or an array of paths*   to search.* @return void* @throws Zend_Exception*/public static function loadClass($class, $dirs = null){    if (class_exists($class, false) || interface_exists($class, false)) {      return;    }    if ((null !== $dirs) && !is_string($dirs) && !is_array($dirs)) {      require_once 'Zend/Exception.php';      throw new Zend_Exception('Directory argument must be a string or an array');    }    // Autodiscover the path from the class name    // Implementation is PHP namespace-aware, and based on    // Framework Interop Group reference implementation:    // http://groups.google.com/group/php-standards/web/psr-0-final-proposal    $className = ltrim($class, '\\');    $file   = '';    $namespace = '';    if ($lastNsPos = strripos($className, '\\')) {      $namespace = substr($className, 0, $lastNsPos);      $className = substr($className, $lastNsPos + 1);      $file   = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;    }    $file .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';    if (!empty($dirs)) {      // use the autodiscovered path      $dirPath = dirname($file);      if (is_string($dirs)) {        $dirs = explode(PATH_SEPARATOR, $dirs);      }      foreach ($dirs as $key => $dir) {        if ($dir == '.') {          $dirs[$key] = $dirPath;        } else {          $dir = rtrim($dir, '\\/');          $dirs[$key] = $dir . DIRECTORY_SEPARATOR . $dirPath;        }      }      $file = basename($file);      self::loadFile($file, $dirs, true);    } else {      self::loadFile($file, null, true);    }    if (!class_exists($class, false) && !interface_exists($class, false)) {      require_once 'Zend/Exception.php';      throw new Zend_Exception("File \"$file\" does not exist or class \"$class\" was not found in the file");    }}

$class 类名将会根据下划线(作为目录分隔线)对应到相应目录下的PHP文件,并加上'.php',比如Container_Tree会指向Container\\Tree.php。
$dir     可以是数组或者字符串。目录是除去类名包含的目录的路径。

3.判断某个文件是否可读

具体使用:

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

具体实现:

/** * Returns TRUE if the $filename is readable, or FALSE otherwise. * This function uses the PHP include_path, where PHP's is_readable() * does not. * * Note from ZF-2900: * If you use custom error handler, please check whether return value * from error_reporting() is zero or not. * At mark of fopen() can not suppress warning if the handler is used. * * @param string  $filename * @return boolean */public static function isReadable($filename){  if (is_readable($filename)) {    // Return early if the filename is readable without needing the    // include_path    return true;  }  if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN'    && preg_match('/^[a-z]:/i', $filename)  ) {    // If on windows, and path provided is clearly an absolute path,    // return false immediately    return false;  }  foreach (self::explodeIncludePath() as $path) {    if ($path == '.') {      if (is_readable($filename)) {        return true;      }      continue;    }    $file = $path . '/' . $filename;    if (is_readable($file)) {      return true;    }  }  return false;}

具体参数:

$filename参数指定了要检查的文件名,包括路径信息。这个方法是将 PHP 函数» is_readable()封装而成的,is_readable() 不会自动查找 include_path 下的文件,而 Zend::isReadable() 可以。

4.Autoloader

这个类的Autoloader功能已经不推荐使用了,所以不再讲述。还有其他的Autoloader,以后具体说明。

5.插件加载器

帮助文章给出的具体实例如下,可参考使用:

很多 Zend Framework 组件支持插件,允许通过指定类的前缀和到类的文件(不需要在 include_path或不需要遵循传统命名约定的文件)的路径动态加载函数。Zend_Loader_PluginLoader 提供了普通的函数来完成这个工作。

PluginLoader 的基本用法遵循 Zend Framework 的命名约定(一个文件一个类),解析路径时,使用下划线作为路径分隔符。当决定是否加载特别的插件类,允许传递可选的类前缀来预处理。另外,路径按 LIFO 顺序来搜索。由于 LIFO 搜索和类的前缀,允许命名空间给插件,这样可以从早期注册的路径来覆盖插件。

基本用例

首先,假定下面的目录结构和类文件,并且根(toplevel)目录和库目录在 include_path 中:

application/
    modules/
        foo/
            views/
                helpers/
                    FormLabel.php
                    FormSubmit.php
        bar/
            views/
                helpers/
                    FormSubmit.php
library/
    Zend/
        View/
            Helper/
                FormLabel.php
                FormSubmit.php
                FormText.php

现在,创建一个插件加载器来使各种各样的视图助手仓库可用:

addPrefixPath('Zend_View_Helper', 'Zend/View/Helper/')    ->addPrefixPath('Foo_View_Helper', 'application/modules/foo/views/helpers')    ->addPrefixPath('Bar_View_Helper', 'application/modules/bar/views/helpers');?>

接着用类名中添加路径时定义的前缀后面的部分来加载一个给定的视图助手:

load('FormText'); // 'Zend_View_Helper_FormText';// load 'FormLabel' helper:$formLabelClass = $loader->load('FormLabel'); // 'Foo_View_Helper_FormLabel'// load 'FormSubmit' helper:$formSubmitClass = $loader->load('FormSubmit'); // 'Bar_View_Helper_FormSubmit'?>

类加载后,就可以实例化了。

Note: 为一个前缀注册多个路径

有时候,多个路径使用相同的前缀,Zend_Loader_PluginLoader 实际上为每个给定的前缀注册一个路径数组;最后注册的被首先检查,当你使用孵化器里的组件时,这相当有用。

Note: 实例化时定义路径

你可以提供给构造器一个可选的“前缀/路径”对(或“前缀/多个路径”)数组参数:

 'Zend/View/Helper/',  'Foo_View_Helper' => 'application/modules/foo/views/helpers',  'Bar_View_Helper' => 'application/modules/bar/views/helpers'));?>

Zend_Loader_PluginLoader 在不需要使用单态实例的情况下,也可选地允许共享插件,这是通过静态注册表来完成的,在实例化时需要注册表名作为构造器的第二个参数:

其它使用同名注册表来实例化 PluginLoader 的组件将可以访问已经加载的路径和插件。

处理插件路径

上节的例子示例如何给插件加载器添加路径,那么如何确定已经加载的路径或删除他们呢?

如果没有提供 $prefix,getPaths($prefix = null) 以“前缀/路径”对返回所有的路径;或者如果提供了 $prefix,getPaths($prefix = null) 返回为给定的前缀注册的路径。

clearPaths($prefix = null) 将缺省地清除所有的已注册路径,或者如果提供了 $prefix 并放在堆栈里,只清除和那些和给定前缀关联的路径。

removePrefixPath($prefix, $path = null) 允许有选择地清除和给定前缀相关的特定的路径。如果没有提供 $path ,所有的和前缀相关的路径被清除,如果提供了 $path 并且相应的前缀存在,只有这个相关的路径被清除。
测试插件和获取类的名字

有时候你想确定在执行一个动作之前是否插件类已经加载,isLoaded() 返回插件名的状态。

PluginLoader 的另一个普通用例是确定已加载类的完全合格的插件类名,getClassName() 提供该功能。一般地,这个和 isLoaded() 联合使用:

isLoaded('Adapter')) {  $class  = $loader->getClassName('Adapter');  $adapter = call_user_func(array($class, 'getInstance'));}?>

具体插件加载器的实现可以参考Zend_Loader_PluginLoader和Zend_Loader。这里不在累述。

更多关于zend相关内容感兴趣的读者可查看本站专题:《Zend FrameWork框架入门教程》、《php优秀开发框架总结》、《Yii框架入门及常用技巧总结》、《ThinkPHP入门教程》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家PHP程序设计有所帮助。

您可能感兴趣的文章:

  • Zend Framework连接Mysql数据库实例分析
  • 解析如何使用Zend Framework 连接数据库
  • zend framework配置操作数据库实例分析
  • Zend Framework框架教程之Zend_Db_Table_Rowset用法实例分析
  • Zend Framework教程之Zend_Db_Table_Row用法实例分析
  • Zend Framework教程之Zend_Db_Table用法详解
  • Zend Framework入门知识点小结
  • Zend Framework缓存Cache用法简单实例
  • Zend Framework基本页面布局分析
  • Zend Framework教程之配置文件application.ini解析
  • Zend Framework教程之MVC框架的Controller用法分析
  • Zend Framework教程之连接数据库并执行增删查的方法(附demo源码下载)


  • 上一条:
    Zend Framework教程之配置文件application.ini解析
    下一条:
    Zend Framework教程之Autoloading用法详解
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Filament v3.1版本发布(0个评论)
    • docker + gitea搭建一个git服务器流程步骤(0个评论)
    • websocket的三种架构方式使用优缺点浅析(0个评论)
    • ubuntu20.4系统中宿主机安装nginx服务,docker容器中安装php8.2实现运行laravel10框架网站(0个评论)
    • phpstudy_pro(小皮面板)中安装最新php8.2.9版本流程步骤(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2018-05
    • 2020-02
    • 2020-03
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-11
    • 2021-03
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-08
    • 2023-08
    • 2023-10
    • 2023-12
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客