PHP中的插件机制原理和实例


Posted in PHP onJuly 08, 2014

PHP项目中很多用到插件的地方,更尤其是基础程序写成之后很多功能由第三方完善开发的时候,更能用到插件机制,现在说一下插件的实现。特点是无论你是否激活,都不影响主程序的运行,即使是删除也不会影响。

从一个插件安装到运行过程的角度来说,主要是三个步骤:

1.插件安装(把插件信息收集进行采集和记忆的过程,比如放到数据库中或者XML中)

2.插件激活(打开插件,让监听插件的地方开始进行调用)

3.插件运行(插件功能的实现)

从一个插件的运行上来说主要以下几点:

1.插件的动态监听和加载(插件的信息获取)

2.插件的动态触发(插件的运行)

一个完善的插件系统主要包括以下:

1.插件安装及卸载

2.插件打开与关闭

3.插件信息获取

4.插件调度(插件经理)

5.插件主体

在程序的编写上主要实现以下:

1.插件的注册和初始化

2.判断激活条件

3.钩子激活

4.运行插件

实例代码:

<?php
/** 
* PluginManager Class 
* 
* 插件机制的实现核心类 
* 
* @link https://3water.com/ 
*/ 
class PluginManager 
{ 
  /** 
   * 监听已注册的插件 
   * 
   * @access private 
   * @var array 
   */ 
  private $_listeners = array(); 
   /** 
   * 构造函数 
   * 
   * @access public 
   * @return void 
   */ 
  public function __construct() 
  { 
    #这里$plugin数组包含我们获取已经由用户激活的插件信息 
   #为演示方便,我们假定$plugin中至少包含 
   #$plugin = array( 
    #  'name' => '插件名称', 
    #  'directory'=>'插件安装目录' 
    #); 
   
 
   // $plugins = get_active_plugins();#这个函数请自行实现 
 
    //函数实现后的最终数据结构效果如下
    $plugins=array(array("directory"=>"demo",
    "name"=>"DEMO"));
 
 
    if($plugins) 
    { 
      foreach($plugins as $plugin) 
 
      {//假定每个插件文件夹中包含一个actions.php文件,它是插件的具体实现 
        if (@file_exists(STPATH .'plugins/'.$plugin['directory'].'/actions.php')) 
        { 
          include_once(STPATH .'plugins/'.$plugin['directory'].'/actions.php'); 
          $class = $plugin['name'].'_actions'; 
          if (class_exists($class)) 
          { 
            //初始化所有插件 
            //$this 是本类的引用
            new $class($this); 
          } 
        } 
      } 
    } 
    #此处做些日志记录方面的东西 
  } 
 
  /** 
   * 注册需要监听的插件方法(钩子) 
   * 
   * @param string $hook 
   * @param object $reference 
   * @param string $method 
   */ 
  function register($hook, &$reference, $method) 
  { 
    //获取插件要实现的方法 
    $key = get_class($reference).'->'.$method; 
    //将插件的引用连同方法push进监听数组中 
    $this->_listeners[$hook][$key] = array(&$reference, $method); 
    #此处做些日志记录方面的东西 
  } 
  /** 
   * 触发一个钩子 
   * 
   * @param string $hook 钩子的名称 
   * @param mixed $data 钩子的入参 
   *  @return mixed 
   */ 
  function trigger($hook, $data='') 
  { 
    $result = ''; 
    //查看要实现的钩子,是否在监听数组之中 
    if (isset($this->_listeners[$hook]) && is_array($this->_listeners[$hook]) && count($this->_listeners[$hook]) > 0) 
    { 
      // 循环调用开始 
      foreach ($this->_listeners[$hook] as $listener) 
      { 
        // 取出插件对象的引用和方法 
        $class =& $listener[0]; 
        $method = $listener[1]; 
        if(method_exists($class,$method)) 
        { 
          // 动态调用插件的方法 
          $result .= $class->$method($data); 
        } 
      } 
    } 
    #此处做些日志记录方面的东西 
    return $result; 
  } 
} 
 
define(STPATH, "./");
 
$pluginManager=new PluginManager();
 
$pluginManager->trigger("demo");

demo插件文件:

<?php
/**
 * 这是一个Hello World简单插件的实现
 *
 * @link    https://3water.com/
 */
/**
 *需要注意的几个默认规则:
 *  1. 本插件类的文件名必须是action
 *  2. 插件类的名称必须是{插件名_actions}
 */
class DEMO_actions
{
  //解析函数的参数是pluginManager的引用
  function __construct(&$pluginManager)
  {
    //注册这个插件
    //第一个参数是钩子的名称
    //第二个参数是pluginManager的引用
    //第三个是插件所执行的方法
    $pluginManager->register('demo', $this, 'say_hello');
  }
 
  function say_hello()
  {
    echo 'Hello World';
  }
}
PHP 相关文章推荐
利用PHP动态生成VRML网页
Oct 09 PHP
Windows中安装Apache2和PHP4权威指南
Nov 18 PHP
PHP通用检测函数集合
Nov 25 PHP
php学习之变量的使用
May 29 PHP
php中判断文件空目录是否有读写权限的函数代码
Aug 07 PHP
解析在PHP中使用mysqli扩展库对mysql的操作
Jul 03 PHP
codeigniter数据库操作函数汇总
Jun 12 PHP
PHP错误Cannot use object of type stdClass as array in错误的解决办法
Jun 12 PHP
ThinkPHP实现动态包含文件的方法
Nov 29 PHP
PHP实现APP微信支付的实例讲解
Feb 10 PHP
wordpress自定义标签云与随机获取标签的方法详解
Mar 22 PHP
实现laravel 插入操作日志到数据库的方法
Oct 11 PHP
phpmailer在服务器上不能正常发送邮件的解决办法
Jul 08 #PHP
php去掉URL网址中带有PHPSESSID的配置方法
Jul 08 #PHP
PHP大批量插入数据库的3种方法和速度对比
Jul 08 #PHP
php发送get、post请求的6种方法简明总结
Jul 08 #PHP
PHP中对各种加密算法、Hash算法的速度测试对比代码
Jul 08 #PHP
微信公众平台天气预报功能开发
Jul 06 #PHP
最常用的8款PHP调试工具
Jul 06 #PHP
You might like
浅析SVN常见问题及解决方法
2013/06/21 PHP
PHP解压tar.gz格式文件的方法
2016/02/14 PHP
php将html转为图片的实现方法
2017/05/19 PHP
JavaScript网页制作特殊效果用随机数
2007/05/22 Javascript
Web开发者必备的12款超赞jQuery插件
2010/12/03 Javascript
poshytip 基于jquery的 插件 主要用于显示微博人的图像和鼠标提示等
2012/10/12 Javascript
JavaScript中的比较操作符&gt;、=、
2014/12/31 Javascript
js库Modernizr的介绍和使用
2015/05/07 Javascript
js淡入淡出焦点图幻灯片效果代码分享
2015/09/08 Javascript
使用jQuery获取data-的自定义属性
2015/11/10 Javascript
js判断复选框是否选中及选中个数的实现代码
2016/05/30 Javascript
详解js产生对象的3种基本方式(工厂模式,构造函数模式,原型模式)
2017/01/09 Javascript
javascript数据结构中栈的应用之符号平衡问题
2017/04/11 Javascript
vue2.x 父组件监听子组件事件并传回信息的方法
2017/07/17 Javascript
javascript设计模式 ? 迭代器模式原理与用法实例分析
2020/04/17 Javascript
Nuxt的路由配置和参数传递方式
2020/11/06 Javascript
Nuxt的动态路由和参数校验操作
2020/11/09 Javascript
vue+Element-ui实现登录注册表单
2020/11/17 Javascript
使用Python实现一个简单的项目监控
2015/03/31 Python
python获取指定目录下所有文件名列表的方法
2015/05/20 Python
Python设计模式之状态模式原理与用法详解
2019/01/15 Python
python 判断linux进程,并杀死进程的实现方法
2019/07/01 Python
详解用python生成随机数的几种方法
2019/08/04 Python
在Django下测试与调试REST API的方法详解
2019/08/29 Python
Python通过kerberos安全认证操作kafka方式
2020/06/06 Python
Python unittest基本使用方法代码实例
2020/06/29 Python
Django REST 异常处理详解
2020/07/15 Python
计算机毕业大学生推荐信
2013/12/01 职场文书
大学生开西餐厅创业计划书
2014/02/01 职场文书
入党思想汇报怎么写
2014/04/03 职场文书
竞选班长的演讲稿
2014/04/24 职场文书
承诺书范本
2015/01/21 职场文书
肖申克救赎观后感
2015/06/02 职场文书
图书馆义工感想
2015/08/07 职场文书
创业计划书之酒店
2019/08/30 职场文书
Python中os模块的简单使用及重命名操作
2021/04/17 Python