插件概念

来自 http://www.jb51.net/article/51980.htm

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

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

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

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

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

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

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

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

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

1.插件安装及卸载

2.插件打开与关闭

3.插件信息获取

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

5.插件主体

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

1.插件的注册和初始化

2.判断激活条件

3.钩子激活

4.运行插件

实例代码:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

<?php

/**

* PluginManager Class

*

* 插件机制的实现核心类

*

* @link http://www.jb51.net/

*/

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插件文件:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

<?php

/**

 * 这是一个Hello World简单插件的实现

 *

 * @link    http://www.jb51.net/

 */

/**

 *需要注意的几个默认规则:

 *  1. 本插件类的文件名必须是action

 *  2. 插件类的名称必须是{插件名_actions}

 */

class DEMO_actions

{

  //解析函数的参数是pluginManager的引用

  function __construct(&$pluginManager)

  {

    //注册这个插件

    //第一个参数是钩子的名称

    //第二个参数是pluginManager的引用

    //第三个是插件所执行的方法

    $pluginManager->register(‘demo‘, $this, ‘say_hello‘);

  }

 

  function say_hello()

  {

    echo ‘Hello World‘;

  }

}

时间: 2024-10-12 17:31:04

插件概念的相关文章

软件架构、框架、模式、模块、组件、插件概念汇总

术语 英文解释 中文解释 架构 architecture: Architecture is the art of planning, designing, and constructing buildings. 架构名词起源于建筑,没有明确标准的定义描述,不同人基于经验对它理解也多少会有差异.实际上架构就是指人们根据自己对世界的认识,为解决某个问题,主动地.有目的地去识别问题,并进行分解.合并,解决这个问题的实践活动.架构的产出物,自然就是对问题的分析,以及解决问题的方案:包括拆分的原则以及理由

转:自己动手写插件框架(1)

转自:http://www.devbean.net/2012/03/building-your-own-plugin-framework-1/ 本系列文章来自 Building Your Own Plugin Framework,主要内容是讨论使用 C/C++ 语言开发跨平台的插件框架所需要的架构.开发方法以及部署.我们将从分析现有插件/组件系统开始,一步步深入了解如何开发插件框架,以及很多需要注意的问题,比如二进制兼容性等,在文章的最后,我们将给出一个比较合理的解决方案. 在本系列文章中,我们

如何创建一个基本JQuery的插件

如何创建一个基本的插件 有时您希望在整个代码中提供一些功能.例如,也许你想要一个单一的方法,你可以调用一个jQuery选择,对选择执行一系列的操作.在这种情况下,您可能需要编写一个插件. 链接jQuery如何工作101:jQuery对象方法 在我们编写自己的插件之前,首先要了解一下jQuery如何工作.看看这段代码: 1 $( "a" ).css( "color", "red" ); 这是一些很基础的jQuery代码,但你知道幕后发生了什么吗?无

Android插件化探索(一)类加载器DexClassLoader

本文部分内容参考自<Android内核剖析> 基本概念 在Java环境中,有个概念叫做"类加载器"(ClassLoader),其作用是动态装载Class文件.标准的Java SDK中有一个ClassLoader类,借助它可以装载想要的Class文件,每个ClassLoader对象在初始化时必须指定Class文件的路径 没有使用过ClassLoader的读者可能会问:"在过去的程序开发中,当我们需要某个类时,只需使用import关键字包含该类就可以了,为什么还要类加

关于 Java 性能监控您不知道的 5 件事,第 1 部分

责怪糟糕的代码(或不良代码对象)并不能帮助您发现瓶颈,提高 Java? 应用程序速度,猜测也不能帮您解决.Ted Neward 引导您关注 Java 性能监控工具,从5 个技巧开始,使用Java 5 的内置分析器JConsole 收集和分析性能数据. 当应用程序性能受到损害时,大多数开发人员都惊慌失措,这在情理之中.跟踪 Java 应用程序瓶颈来源一直以来都是很麻烦的,因为 Java 虚拟机有黑盒效应,而且 Java 平台分析工具一贯就有缺陷. 然而,随着 Java 5 中 JConsole 的

熟悉Eclipse开发工具

一.熟悉Eclipse 1.Eclipse是由IBM公司投资4000万美元开发的集成开发工具.它基于Java语言编写,并且是开放源代码的.可扩展的,也是目前最流行的Java集成开发工具之一.另外,IBM公司捐出Eclipse源代码,组建了Eclipse联盟,由该联盟负责这种工具的后续开发.Eclipse为编程人员提供了一流的Java程序开发环境,它的平台体系结构是在插件概念的基础上构建的,插件是Eclipse平台最具特色的特征之一,也是其区别于其他开发工具的特征之一. 2.下载Eclipse 步

JDK自带的监控分析工具JConsole

非常多开发人员认为自己懂Java编程.事实是大多数开发人员都仅仅领会到了Java平台的皮毛.所学也仅仅够应付工作. 作者将深度挖掘Java平台的核心功能.揭示一些鲜为人知的事实.帮助您解决最棘手的编程困难. 当应用程序性能受到损害时,大多数开发者都惊慌失措.这在情理之中. 跟踪Java应用程序瓶颈来源一直以来都是非常麻烦的,由于Java虚拟机有黑盒效应,并且Java平台分析工具一贯就有缺陷. 然而,随着Java5中JConsole的引入,一切都发生了改变. JConsole是一个内置Java性能

使用 Equinox 开发 OSGi 应用程序

本教程着重介绍 OSGi 框架知识.环境搭建.服务使用.应用设计.部署. 开始之前 关于本教程 OSGi 是目前动态模块系统的事实上的工业标准,虽然一开始只是作为嵌入式设备和家庭网关的框架来使用,但是实际上它适用于任何需要模块化.面向服务.面向组件的应用程序.而 Equinox 则是的 Eclipse 所使用的 OSGi 框架,是 Eclipse 强大的插件体系的基础,Eclipse 的稳定可靠性也为该框架带来了声誉. 本教程就将演示如何在 Eclipse 环境下利用 Equinox 框架进行

Docker 1.13 – 新增功能大揭秘

前言 Docker 1.13 马上就要发布了.从 7 月 29 日发布 1.12 发布以来,已经过去 4 个多月了,对于活跃的 Docker 社区来说,已经很久了,让我们看看都 1.13 都新增了什么内容吧. 1.13 有一千二百多个 issue/pull request,四千多个 commits,是历史上最高的.这并不是一个简单的小版本变化,里面有大量的更新. 要想测试 1.13.0 的新功能,可以起一个新的机器,然后在里面运行:curl -fsSL https://test.docker.c