thinkphp插件钩子的实现机制是什么

来源:undefined 2024-12-31 04:50:34 1034

现在主流的cms或者blog等系统中,都内置的有插件系统,但是层层深入、剖析实现的方式,其实都是最简单的钩子的复杂化的实现。

前言

插件的执行通过钩子来触发;可以把插件看作挂在钩子上的东西;插件只有在成功实现相应钩子方法并被正确安装启用后才能执行。

开发者也可以用hook(test)方法在控制器只加入钩子,让你的应用具有更好的扩展性;同时也可以模板里加入钩子{:hook(footer)};钩子也支持传入参数hook(footer,array(test=>1));

向系统暴露你的钩子,就是把你的钩子在相应的文件里列出来,系统会来检测。

1

{:hooks(documentDetailAfter)}

登录后复制

这个的意思就是:相当于在这边 打一个点 ,我们可以将插件挂载到那

官方的说法是:文档末尾显示显示的 钩子

意思就是说,在文档末尾的时候,会自动调用挂载在那个 钩子 上的插件

举例说明

php中所谓的钩子,其实就是一种事件驱动,主要分为‘注册事件’、‘触发事件’两步。所谓‘注册事件’,即目的是给未来可能发生的事情起一个名字,名字,可以用单例模式或者注册 为一个全局的变量,用的时候直接在对应的方法或者类再或者函数中插入这个变量即可;‘触发事件’,本质上就是在事件的全局变量中查询要触发的时间名称,然后找到注册号的类与方法,实例化运行。

举个例子来说明一下。

项目经理给我们了如下的需求:

第一天:开发注册的功能。

程序员巴拉巴拉,三下五除二就完成了。

第二天:在注册前添加发送短信验证码的功能。

程序员巴拉巴拉,三峡五除二就又完成了。

第三天:注册完成之后,给用户添加相应的积分。

程序员又开始巴拉巴拉ing……

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

class Register{

public function index(){

/**

* 第二天发送短信功能

*/

/**

* 第一天注册代码

*/

/**

* 第三天增加积分功能 

*/

}

}

登录后复制

这样一个人开发还好,多个人开发,势必会造成配合麻烦的问题,同时代码也会变得混乱。

作为优秀程序员的我们,当然不容许我们程序中代码冗余、混乱的出现,于是我们把方法写成函数独立出来,方便调用与代码简介。于是形成如下代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

class Register{

public function index(){

/**

* 第二天发送短信功能

*/

sendMsg($data);

/**

* 第一天注册代码

*/

/**

* 第三天增加积分功能 

*/

sendIntegral($data);

}

}

/**

* 发送短信

* @param  {[type]} $data [description]

* @return {[type]}       [description]

*/

function sendMsg($data){

/*

balabala

*/

}

/**

* 赠送积分

* @param  {[type]} $data [description]

* @return {[type]}       [description]

*/

function sendIntegral($data){

/*

balabala

*/

}

登录后复制

但是我们想要把程序开元出去让更多的人参与,这种直接修改源码码的方式始终不是太好,这个时候,我们就可以使用钩子的方式,在注册成功前后注册两个钩子,我们只需要把钩子告诉开发人员就行了,这样他们不用改变源码码就可以轻易的进行拓展。

1

2

3

4

5

6

7

8

9

10

11

12

13

class Register{

public function index(){

//注册前钩子

Hook::run(registerBefore);

/**

* 注册代码

*/

//注册后钩子

Hook::run(registerAfter);

}

}

登录后复制

钩子的简单实现代码

目录结构:../hook/Hook.php

钩子核心类Hook.php:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

<?php    

namespace hook;

class Hook{

static protected $hook = [];

/**

* 插件注册

* @param [type] $name   [description]

* @param [type] $addons [description]

*/

static public function add($name,$addons){

self::$hook[$name] = $addons;

}

/**

* 插件执行

* @param  [type] $name [description]

* @return [type]       [description]

*/

static public function run($name){

if(isset(self::$hook[$name])){

$method = (new self::$hook[$name]());

call_user_func([$method,$name]);

}

}

}

登录后复制
简单的插件demo:

1

2

3

4

5

6

7

8

9

<?php     namespace addonsdemo;

class Demo{

public function registerBefore(){

echo &#39;registerBefore&#39;.&#39;</br>;

}

public function registerAfter(){

echo registerAfter.;

}    

}

登录后复制
插件实现的地方,即上文的注册的文件:

1

2

3

4

5

6

7

8

9

10

<?php     namespace indexcontroller;

use hookHook;

class Index{

public function index(){

Hook::run(&#39;registerBefore&#39;);

echo &#39;注册完成&#39;.&#39;</br>;

Hook::run(registerAfter);

}

}

登录后复制
入口文件index.php

1

2

3

4

5

6

7

8

9

10

11

<?php     use indexcontrollerIndex;

spl_autoload_register(&#39;autoload&#39;);

function autoload($name){

require_once(&#39;/&#39;.str_replace(&#39;&#39;,&#39;/&#39;,$name).&#39;.php&#39;);

}

//插件注册

hookHook::add(&#39;registerBefore&#39;,&#39;ddonsdemoDemo&#39;);

hookHook::add(&#39;registerAfter&#39;,&#39;ddonsdemoDemo&#39;);

//调用

$index = new Index();

$index->index();

登录后复制
运行接口如下:    registerBefore    注册完成    registerAfter

如果要添加新的功能,程序员只要修改demo的插件就可,如果要拓展新的功能,只需要拓展registerBefore和registerAfter即可。 

以上就是thinkphp插件钩子的实现机制是什么的详细内容,更多请关注php中文网其它相关文章!

最新文章