上一篇文章中已经说了PHP插件机制的实现理论,这篇文章就主要是附上了一篇例子。本例子也主要借鉴了网上一些网友的方式做了稍微的改造。如果已经了解了原理的朋友可以直接拿来继续改造和使用,如果还不太了解原理的朋友请继续去看一下上一篇文章,文章地址:PHP插件机制写法http://www.chhua.com/web-note4136

好了,不多说了,上例子

test.php 文件:

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

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.chhua.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';
    }
}

 

自由转载,转载请注明: 转载自WEB开发笔记 www.chhua.com

本文链接地址: PHP 插件机制代码演示 http://www.chhua.com/web-note4139

相关笔记

更多