swipe类网站,免费发布的空间,网站建设与维护合同,win7做网站插件#xff0c;亦即Plug-in#xff0c;是指一类特定的功能模块#xff08;通常由第三方开发者实现#xff09;#xff0c;它的特点是#xff1a;当你需要它的时候激活它#xff0c;不需要它的时候禁用/删除它#xff1b;且无 论是激活还是禁用都不影响系统核心模块的运… 插件亦即Plug-in是指一类特定的功能模块通常由第三方开发者实现它的特点是当你需要它的时候激活它不需要它的时候禁用/删除它且无 论是激活还是禁用都不影响系统核心模块的运行也就是说插件是一种非侵入式的模块化设计实现了核心程序与插件程序的松散耦合。一个典型的例子就是 Wordpress中众多的第三方插件比如Akimet插件用于对用户的评论进行Spam过滤。一个健壮的插件机制我认为必须具备以下特点 插件的动态监听和加载Lookup 插件的动态触发 以上两点的实现均不影响核心程序的运行 要在程序中实现插件我们首先应该想到的就是定义不同的钩子Hooks“钩子”是一个很形象的逻辑概念你可以认为它是系统预留的插件触发条件。它 的逻辑原理如下当系统执行到某个钩子时会判断这个钩子的条件是否满足如果满足会转而先去调用钩子所制定的功能然后返回继续执行余下的程序如果 不满足跳过即可。这有点像汇编中的“中断保护”逻辑。某些钩子可能是系统事先就设计好的比如之前我举的关于评论Spam过滤的钩子通常它已经由核心系统开发人员设计进了评论的处理逻辑中另外一类钩子则 可能是由用户自行定制的由第三方开发人员制定通常存在于表现层比如一个普通的PHP表单显示页面中。可能你感觉上面的话比较无聊让人昏昏欲睡但是要看懂下面我写的代码理解以上的原理是必不可少的。下面进行PHP中插件机制的核心实现整个机制核心分为三大块 一个插件经理类这是核心之核心。它是一个应用程序全局Global对象。它主要有三个职责 负责监听已经注册了的所有插件并实例化这些插件对象。 负责注册所有插件。 当钩子条件满足时触发对应的对象方法。 插件的功能实现这大多由第三方开发人员完成但需要遵循一定的规则这个规则是插件机制所规定的因插件机制的不同而不同下面的显 示代码你会看到这个规则。 插件的触发也就是钩子的触发条件。具体来说这是一小段代码放置在你需要插件实现的地方用于触发这个钩子。 原理讲了一大堆下面看看我的实现方案插件经理PluginManager类 1 ?2 /**3 * STBLOG PluginManager Class4 *5 * 插件机制的实现核心类6 *7 * package STBLOG8 * subpackage Libraries9 * category Libraries10 * author Saturn11 */12 class PluginManager13 {14 /**15 * 监听已注册的插件16 *17 * access private18 * var array19 */20 private $_listeners array();21 /**22 * 构造函数23 * 24 * access public25 * return void26 */27 public function __construct()28 {29 #这里$plugin数组包含我们获取已经由用户激活的插件信息30 #为演示方便我们假定$plugin中至少包含31 #$plugin array(32 # name 插件名称,33 # directory插件安装目录34 #);35 $plugins get_active_plugins();#这个函数请自行实现36 if($plugins)37 {38 foreach($plugins as $plugin)39 {//假定每个插件文件夹中包含一个actions.php文件它是插件的具体实现40 if (file_exists(STPATH .plugins/.$plugin[directory]./actions.php))41 {42 include_once(STPATH .plugins/.$plugin[directory]./actions.php);43 $class $plugin[name]._actions;44 if (class_exists($class)) 45 {46 //初始化所有插件47 new $class($this);48 }49 }50 }51 }52 #此处做些日志记录方面的东西53 }54 55 /**56 * 注册需要监听的插件方法钩子57 *58 * param string $hook59 * param object $reference60 * param string $method61 */62 function register($hook, $reference, $method)63 {64 //获取插件要实现的方法65 $key get_class($reference).-.$method;66 //将插件的引用连同方法push进监听数组中67 $this-_listeners[$hook][$key] array($reference, $method);68 #此处做些日志记录方面的东西69 }70 /**71 * 触发一个钩子72 *73 * param string $hook 钩子的名称74 * param mixed $data 钩子的入参75 * return mixed76 */77 function trigger($hook, $data)78 {79 $result ;80 //查看要实现的钩子是否在监听数组之中81 if (isset($this-_listeners[$hook]) is_array($this-_listeners[$hook]) count($this-_listeners[$hook]) 0)82 {83 // 循环调用开始84 foreach ($this-_listeners[$hook] as $listener)85 {86 // 取出插件对象的引用和方法87 $class $listener[0];88 $method $listener[1];89 if(method_exists($class,$method))90 {91 // 动态调用插件的方法92 $result . $class-$method($data);93 }94 }95 }96 #此处做些日志记录方面的东西97 return $result;98 }99 }
100 ? 以上代码加上注释不超过100行就完成了整个插件机制的核心。需要再次说明的是你必须将它设置成全局类在所有 需要用到插件的地方优先加载。用#注释的地方是你需要自行完成的部分包括插件的获取和日志记录等等。下面是一个简单插件的实现。 1 ?2 /**3 * 这是一个Hello World简单插件的实现4 *5 * package DEMO6 * subpackage DEMO7 * category Plugins8 * author Saturn9 */
10 /**
11 *需要注意的几个默认规则
12 * 1. 本插件类的文件名必须是action
13 * 2. 插件类的名称必须是{插件名_actions}
14 */
15 class DEMO_actions
16 {
17 //解析函数的参数是pluginManager的引用
18 function __construct($pluginManager)
19 {
20 //注册这个插件
21 //第一个参数是钩子的名称
22 //第二个参数是pluginManager的引用
23 //第三个是插件所执行的方法
24 $pluginManager-register(demo, $this, say_hello);
25 }
26
27 function say_hello()
28 {
29 echo Hello World;
30 }
31 }
32 ? 这是一个简单的Hello World插件用于输出一句话。在实际情况中say_hello可能包括对数据库的操作或者是其他一些特定的逻辑比如调用Akimet API。插件实现的默认规则由核心系统开发者自行确定。比如本例的一些默认规则我在注释中已经写的很清楚在此不在赘述。需要特别注意的是钩子名称不要重复。最后一步就是定义钩子的触发你将钩子放在哪里上面这个插件的方法就会在哪里出发。比如我要将say_hello放到我博客首页Index.php 那么你在index.php中的某个位置写下 $pluginManager-trigger(demo,); 第一个参数表示钩子的名字在本例中它是demo;第二个参数是插件对应方法的入口参数由于这个例子中没有输入参数所以为空。总结 本篇文章介绍了插件机制在PHP中实现的一种方法和思路以及我本人对插件机制的理解。初次接触这个东西可能会比较生涩难以理解。但是当你结合真实的 例子再想想程序的运行流程思路可能会更清晰一些。 转载于:https://www.cnblogs.com/tianakong/p/10760839.html