经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » PHP » 查看文章
thinkphp(php)插件钩子(hooks)分析的简单实现机制
来源:jb51  时间:2023/3/14 8:46:09  对本文有异议

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

前言

钩子是插件执行的触发器;插件就像挂在钩子上的东西;插件只有实现相应钩子方法,并安装启用成功后才能执行。

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

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

  1. {:hooks('documentDetailAfter')}

这个的意思就是:相当于在这边 打一个点 ,我们可以将插件挂载到那
官方的说法是:文档末尾显示显示的 钩子
意思就是说,在文档末尾的时候,会自动调用挂载在那个 钩子 上的插件

举例说明

php中所谓的钩子,其实就是一种事件驱动,主要分为‘注册事件’、‘触发事件’两步。所谓‘注册事件’,即目的是给未来可能发生的'事情'起一个名字,名字,可以用单例模式或者注册 为一个全局的变量,用的时候直接在对应的方法或者类再或者函数中插入这个变量即可;‘触发事件’,本质上就是在事件的全局变量中查询要触发的时间名称,然后找到注册号的类与方法,实例化运行。
举个例子来说明一下。
项目经理给我们了如下的需求:
第一天:开发注册的功能。
程序员巴拉巴拉,三下五除二就完成了。
第二天:在注册前添加发送短信验证码的功能。
程序员巴拉巴拉,三峡五除二就又完成了。
第三天:注册完成之后,给用户添加相应的积分。
程序员又开始巴拉巴拉ing……

  1. class Register{
  2. public function index(){
  3. /**
  4. * 第二天发送短信功能
  5. */
  6. /**
  7. * 第一天注册代码
  8. */
  9. /**
  10. * 第三天增加积分功能
  11. */
  12. }
  13. }

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

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

  1. class Register{
  2. public function index(){
  3. /**
  4. * 第二天发送短信功能
  5. */
  6. sendMsg($data);
  7. /**
  8. * 第一天注册代码
  9. */
  10. /**
  11. * 第三天增加积分功能
  12. */
  13. sendIntegral($data);
  14. }
  15. }
  16. /**
  17. * 发送短信
  18. * @param {[type]} $data [description]
  19. * @return {[type]} [description]
  20. */
  21. function sendMsg($data){
  22. /*
  23. balabala
  24. */
  25. }
  26. /**
  27. * 赠送积分
  28. * @param {[type]} $data [description]
  29. * @return {[type]} [description]
  30. */
  31. function sendIntegral($data){
  32. /*
  33. balabala
  34. */
  35. }

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

  1. class Register{
  2. public function index(){
  3. //注册前钩子
  4. Hook::run('registerBefore');
  5. /**
  6. * 注册代码
  7. */
  8. //注册后钩子
  9. Hook::run('registerAfter');
  10. }
  11. }

钩子的简单实现代码

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

钩子核心类Hook.php:

  1. <?php
  2. namespace hook;
  3. class Hook{
  4. static protected $hook = [];
  5. /**
  6. * 插件注册
  7. * @param [type] $name [description]
  8. * @param [type] $addons [description]
  9. */
  10. static public function add($name,$addons){
  11. self::$hook[$name] = $addons;
  12. }
  13. /**
  14. * 插件执行
  15. * @param [type] $name [description]
  16. * @return [type] [description]
  17. */
  18. static public function run($name){
  19. if(isset(self::$hook[$name])){
  20. $method = (new self::$hook[$name]());
  21. call_user_func([$method,$name]);
  22. }
  23. }
  24. }

简单的插件demo:

  1. <?php
  2. namespace addons\demo;
  3. class Demo{
  4. public function registerBefore(){
  5. echo 'registerBefore'.'</br>';
  6. }
  7. public function registerAfter(){
  8. echo 'registerAfter'.'</br>';
  9. }
  10. }

插件实现的地方,即上文的注册的文件:

  1. <?php
  2. namespace index\controller;
  3. use hook\Hook;
  4. class Index{
  5. public function index(){
  6. Hook::run('registerBefore');
  7. echo '注册完成'.'</br>';
  8. Hook::run('registerAfter');
  9. }
  10. }

入口文件index.php

  1. <?php
  2. use index\controller\Index;
  3. spl_autoload_register('autoload');
  4. function autoload($name){
  5. require_once('/'.str_replace('\\','/',$name).'.php');
  6. }
  7. //插件注册
  8. hook\Hook::add('registerBefore','\\addons\\demo\\Demo');
  9. hook\Hook::add('registerAfter','\\addons\\demo\\Demo');
  10. //调用
  11. $index = new Index();
  12. $index->index();

运行接口如下:

  •     registerBefore
  •     注册完成
  •     registerAfter

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

总结

可以说,钩子就是挂载点。

挂载点:在系统中提供给你一个挂载点,我们可以进行插件开发,开发完成后,我们将其挂载到 挂载点上,会自动调用执行。

到此这篇关于thinkphp(php)插件钩子(hooks)分析的简单实现机制的文章就介绍到这了,更多相关php插件钩子(hooks)内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号