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目录的,如图:

我们在plugin目录中新建一个test插件,并将需要扩展的代码写进echo_content.hook文件。
on文件表示插件是开启状态。
当代码执行到hook点时,框架会检测开启状态的插件是否有与HOOK点对应的扩展代码,如果有读取HOOK文件中的扩展代码插入的HOOK点
#### echo_content.hook文件:
<?php echo "hello word !!!! "?>
#### 运行程序
程序运行后带有HOOK点的代码会被解析,并被缓存,缓存文件在cache目录中,如图。

打开后,我们可以发现代码已经被解析了
<!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点的前一行多出来了一行我们要插入的代码,并且由于这是缓存,所以程序本身的源代码实际上并没有改变,而且运行的时候运行的是缓存文件。
#### 程序运行结果
