123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- <?php
- namespace Qii\Plugin;
- /**
- * 插件管理
- *
- * @author Zhu Jinhui<jinhui.zhu@live.cn>2015-08-12 15:04
- * @version 1.2
- *
- * 必须实现 __construct(\Qii\Plugins &$pluginManger)方法
- * 用法:
- * class demo implements \Qii\PluginIntf
- * {
- * public function __construct(\Qii\Plugins &$pluginManger)
- * {
- * $pluginManger->register('test1', $this, 'test');
- * $pluginManger->register('test2', $this, 'haha');
- * }
- * public function test()
- * {
- * echo __METHOD__;
- * print_r(func_get_args());
- * }
- * public function haha()
- * {
- * echo __METHOD__;
- * }
- * }
- *
- *
- * $plugins = new Qii\Plugins();
- * $plugins->addPlugin('demo');
- * 执行插件方法 带参数
- * $plugins->trigger('test1', 'argvs1', 'argvs2');
- * 不带参数
- * $plugins->trigger('test2');
- */
- class Plugin
- {
- const VERSION = '1.2';
- //插件列表
- protected $_listeners;
- /**
- * 注册插件到系统
- */
- public function __construct(array $plugins = array())
- {
- if (is_array($plugins)) {
- foreach ($plugins AS $plugin) {
- new $plugin($this);
- }
- }
- }
- /**
- * 添加插件
- * @param string $class 插件类
- */
- public function addPlugin($class)
- {
- new $class($this);
- }
- /**
- * 注册插件
- * @param $hook 钩子名称
- * @param $reference 插件的引用
- * @param $method 钩子对应的方法名
- */
- public 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)
- {
- $result = '';
- $argvs = func_get_args();
- $hook = array_shift($argvs);
- //查看要实现的钩子,是否在监听数组之中
- if (isset($this->_listeners[$hook]) && is_array($this->_listeners[$hook]) && count($this->_listeners[$hook]) > 0) {
- //循环调用开始指定hook中注册的方法,并将结果拼接起来返回
- foreach ($this->_listeners[$hook] as $listener) {
- //取出插件对象的引用和方法
- $class =& $listener[0];
- $method = $listener[1];
- if (method_exists($class, $method)) {
- //动态调用插件的方法
- $result .= call_user_func_array(array($class, $method), $argvs);
- }
- }
- }
- return $result;
- }
- }
|