Plugin.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <?php
  2. namespace Qii\Plugin;
  3. /**
  4. * 插件管理
  5. *
  6. * @author Zhu Jinhui<jinhui.zhu@live.cn>2015-08-12 15:04
  7. * @version 1.2
  8. *
  9. * 必须实现 __construct(\Qii\Plugins &$pluginManger)方法
  10. * 用法:
  11. * class demo implements \Qii\PluginIntf
  12. * {
  13. * public function __construct(\Qii\Plugins &$pluginManger)
  14. * {
  15. * $pluginManger->register('test1', $this, 'test');
  16. * $pluginManger->register('test2', $this, 'haha');
  17. * }
  18. * public function test()
  19. * {
  20. * echo __METHOD__;
  21. * print_r(func_get_args());
  22. * }
  23. * public function haha()
  24. * {
  25. * echo __METHOD__;
  26. * }
  27. * }
  28. *
  29. *
  30. * $plugins = new Qii\Plugins();
  31. * $plugins->addPlugin('demo');
  32. * 执行插件方法 带参数
  33. * $plugins->trigger('test1', 'argvs1', 'argvs2');
  34. * 不带参数
  35. * $plugins->trigger('test2');
  36. */
  37. class Plugin
  38. {
  39. const VERSION = '1.2';
  40. //插件列表
  41. protected $_listeners;
  42. /**
  43. * 注册插件到系统
  44. */
  45. public function __construct(array $plugins = array())
  46. {
  47. if (is_array($plugins)) {
  48. foreach ($plugins AS $plugin) {
  49. new $plugin($this);
  50. }
  51. }
  52. }
  53. /**
  54. * 添加插件
  55. * @param string $class 插件类
  56. */
  57. public function addPlugin($class)
  58. {
  59. new $class($this);
  60. }
  61. /**
  62. * 注册插件
  63. * @param $hook 钩子名称
  64. * @param $reference 插件的引用
  65. * @param $method 钩子对应的方法名
  66. */
  67. public function register($hook, &$reference, $method)
  68. {
  69. //获取插件要实现的方法
  70. $key = get_class($reference) . '->' . $method;
  71. //将插件的引用连同方法push进监听数组中
  72. $this->_listeners[$hook][$key] = array(&$reference, $method);
  73. #此处做些日志记录方面的东西
  74. }
  75. /**
  76. * 触发一个钩子
  77. *
  78. * @param string $hook 钩子的名称
  79. * @param mixed $data 钩子的入参
  80. * @return mixed
  81. */
  82. function trigger($hook)
  83. {
  84. $result = '';
  85. $argvs = func_get_args();
  86. $hook = array_shift($argvs);
  87. //查看要实现的钩子,是否在监听数组之中
  88. if (isset($this->_listeners[$hook]) && is_array($this->_listeners[$hook]) && count($this->_listeners[$hook]) > 0) {
  89. //循环调用开始指定hook中注册的方法,并将结果拼接起来返回
  90. foreach ($this->_listeners[$hook] as $listener) {
  91. //取出插件对象的引用和方法
  92. $class =& $listener[0];
  93. $method = $listener[1];
  94. if (method_exists($class, $method)) {
  95. //动态调用插件的方法
  96. $result .= call_user_func_array(array($class, $method), $argvs);
  97. }
  98. }
  99. }
  100. return $result;
  101. }
  102. }