HOOK扩展

### HOOK扩展 在二次开发项目时,我们常常希望能在不修改程序源代码时,扩展程序的功能。因此,我在设计框架之初,实现了一个简单的HOOK扩展机制。 HOOK扩展机制就是允许我们可以提前在需要扩展的地方布置HOOK点,每当执行到HOOK点时,就会触发扩展代码。只要有HOOK点的地方,开发者都能利用这个HOOK点插入扩展代码。 #### 我的实现思路 我的实现思路就是通过正则匹配找出代码中的所有HOOK点,然后从插件获取与HOOK点相对应的代码,然后将其插入到HOOK点中;处理完后的代码会被缓存,下次运行的时候也不用重新解析。 <?php namespace Trauben; class Extend { public array $extend_file; public string $template_code; public array $extend_onList; public function __construct() { //获取插件列表 $this->extend_file = F(PLUGIN_PATH, 'dir'); //获取已打开的插件 foreach ($this->extend_file as $v) { if (is_file(PLUGIN_PATH . $v . '/' . 'on')) { $this->extend_onList[] = PLUGIN_PATH . $v . '/'; } } } public function hook($code) { //将代码赋值给变量 $this->template_code = $code; //匹配插件HOOK插入点 preg_match_all('{<\!--\s?<hook::/\s(.*?)\s>\s?-->}i', $this->template_code, $array_1); preg_match_all('{//<hook::/\s(.*?)\s>}', $this->template_code, $array_2); $this->parse($array_1); $this->parse($array_2); return $this->template_code; } private function parse($array) { if (!empty($this->extend_onList)) { if (!empty($array[0])) { $exdend_hook = 0; foreach ($array[1] as $v) { foreach ($this->extend_onList as $vv) { if (is_file($vv . $v . '.hook')) { $Include = new Includes(); $tmp_code = $Include->insert($vv . $v . '.hook'); $this->template_code = str_replace($array[0][$exdend_hook], $tmp_code . "\n" . $array[0][$exdend_hook], $this->template_code); } else { continue; } } $exdend_hook += 1; } } } } } #### HOOK的使用 HOOK使用的第一步肯定得在允许扩展的地方布置HOOK点,下面给大家举个例子。 /view/phone/test.tp.php模板文件: <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <!--<hook::/ echo_content >--> </body> </html> 上面的代码中,我在模板中布置了一个名为“echo_content”的HOOK点 第二步我们需要将想要插入的代码写到插件中。 插件是app/plugin目录的,如图: ![45df725b350bba35bfb3560230d7b32.png](https://cos.easydoc.net/21946415/files/lffhmv5y.png) 我们在plugin目录中新建一个test插件,并将需要扩展的代码写进echo_content.hook文件。 on文件表示插件是开启状态。 当代码执行到hook点时,框架会检测开启状态的插件是否有与HOOK点对应的扩展代码,如果有读取HOOK文件中的扩展代码插入的HOOK点 #### echo_content.hook文件: <?php echo "hello word !!!! "?> #### 运行程序 程序运行后带有HOOK点的代码会被解析,并被缓存,缓存文件在cache目录中,如图。 ![dfb7e8137922925e2a79eeb36e229f9.png](https://cos.easydoc.net/21946415/files/lffhv61o.png) 打开后,我们可以发现代码已经被解析了 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <?php echo "hello word !!!" ?> <!--<hook::/ echo_content >--> </body> </html> 可以看到HOOK点的前一行多出来了一行我们要插入的代码,并且由于这是缓存,所以程序本身的源代码实际上并没有改变,而且运行的时候运行的是缓存文件。 #### 程序运行结果 ![3748b69c3d917a57cfe6f6007257815.png](https://cos.easydoc.net/21946415/files/lffhymdn.png)