热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ThinkPHP5行为和钩子-02

绑定行为要给钩子绑定行为有两种方式:配置绑定和动态绑定。配置绑定配置绑定是在应用目录或者模块目录下面的tags.php文件中配置,app_init和app_begin钩子只能在应用目录下面的tag
绑定行为

要给钩子绑定行为有两种方式:配置绑定和动态绑定。

配置绑定

配置绑定是在应用目录或者模块目录下面的 tags.php文件中配置,app_init和app_begin钩子只
能在应用目录下面的 tags.php文件中配置模块目录下面配置无效,而其它的钩子支持应用和模块配置,
如果同时定义的话,会合并后依次执行行为。
以我们上面定义的两个行为为例,配置方式如下:
return [
'app_init'     =>   ['\app\common\behavior\Hello','\app\common\behavior\Test',],
'app_begin'    =>   ['\app\common\behavior\Test',],    
'module_init'  =>  [function($request){            
        echo 'hello,'.$request->module().'!';          
    },],  
];

假设我们的控制器类如下:
namespace app\index\controller;
class Index
{    
    public function index()      
    {        
        return 'run index
';
    }  
}

当我们访问URL
http://contoso.org

后,页面输出结果为:
hello,world! app_init testapp_begin testhello,index! run index

配置绑定的行为执行顺序就是配置的定义顺序,我们修改下配置文件里面的定义顺序如下:
return [
'app_init'     =>   ['\app\common\behavior\Test','\app\common\behavior\Hello',],
'app_begin'    =>   ['\app\common\behavior\Test',],
'module_init'  =>   [function($request){
    echo 'hello,'.$request->module().'!';
    },],
];

最终输出的结果变成:
app_init testhello,world! app_begin testhello,index! run index

如果我希望app_init钩子的Test行为执行后不再继续执行后续的行为,可以修改 Test行为类如下:
namespace app\common\behavior;
class Test
{    
    public function appInit()      
    {        
        echo 'app_init test
';
        return false;
    }    
    public function appBegin()      
    {        
        echo 'app_begin test';        
        return false;      
    }  
}

再次访问的时候,输出结果就变成了
app_init testapp_begin testhello,index! run index

我们看到,app_init钩子绑定的 Hello行为没有被执行。
现在我们在模块的tags.php文件中添加行为绑定
return [
'module_init'   => [function($request){
        echo 'welcome,'.$request->module().'!';
    },],
];

再次访问后页面输出结果为:
app_init test app_begin test hello,index! welcome,index! run index

可见 modue_init钩子上的应用绑定行为和模块绑定行为同时生效了,
如果希望当前模块的行为覆盖应用绑定的行为,可以使用:
return [
'module_init'    =>  [function($request){
    echo 'welcome,'.$request->module().'!';
},        
'_overlay'    =>  true,],
];

再次访问后,查看页面输出结果变成:
app_init testapp_begin testwelcome,index! run index


module_init钩子只执行了模块的行为。

我们给 Test行为增加一个额外的方法并且也绑定到 module_init钩子
namespace app\common\behavior;
class Test
{    
    public function appInit()      
    {        
        echo 'app_init test
';
        return false;
    }    
    public function appBegin()      
    {        
        echo 'app_begin test
';
        return false;
    }    
    public function sayHello($request)      
    {        
        echo 'say hello ' . $request->module() . '!';      
    }  
}


V5.0.4+版本开始支持指定方法(包括静态方法执行行为)

因为sayHello方法和钩子名称( module_init对应的方法名应该是 moduleInit)不一致,
所以我们在绑定行为的时候需要改为:
return [
'module_init'    =>  [function($request){
        echo 'welcome,'.$request->module().'!';
    },         
    ['\app\common\behavior\Test','sayHello'],],
];

再次访问页面输出:
app_init test app_begin test hello,index! welcome,index!say hello index! run index
如果sayHello是一个静态方法的话,绑定方式需要从原来的
['\app\common\behavior\Test','sayHello'],
改为:
'\app\common\behavior\Test::sayHello',


动态绑定

配置方式绑定行为理解之后,我们再来看下如何动态绑定某个行为,动态绑定是指使用 Hook::add方法
动态给钩子添加一个行为方法,格式:

    Hook::add('钩子名称','行为定义','是否优先执行');

如果行为需要在应用里面被绑定,就在应用的公共文件 common.php中使用动态绑定代码,如果是模块的绑定行为,
那么也可以在模块的 common.php文件中使用动态绑定。

保持行为类不变的前提下,我们把前面的配置绑定方式改成动态绑定的方式,
首先在 application/common.php中添加如下代码:
use think\Hook;
Hook::add('app_init',['\app\common\behavior\Test','\app\common\behavior\Hello', ]);
Hook::add('app_begin',['\app\common\behavior\Test', ]);
Hook::add('module_init',[function($request){
        echo 'hello,'.$request->module().'!';
    },]
);

在 application/index/common.php中添加如下代码:
use think\Hook;
Hook::add('module_init',[function($request){
            echo 'welcome,'.$request->module().'!';
        },
        ['\app\common\behavior\Test','sayHello'],
    ]
);

然后清空应用和模块的tags.php文件内容,再次访问测试下,输出结果为:
app_init test app_begin test hello,index! welcome,index!say hello index! run index

效果一致。

示例的行为只是做了一个非常简单的输出操作,其实行为可以做很多的事情,
比如检查访问请求、权限检查、请求对象的属性和方法注入、甚至可以进行路由拦截等等,
你唯一需要注意的就是钩子的生效时间点,以及在这个钩子可以做什么有效操作。
推荐阅读
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 深入理解ThinkPHP5.1自定义标签的应用与实现
    本文详细探讨了ThinkPHP5.1框架中自定义标签的创建与使用方法,包括标签库的建立、模板配置以及在实际项目中的应用技巧。 ... [详细]
  • 本文通过一个具体的用户管理项目,详细介绍如何使用Spring MVC框架进行开发。从用户实体类的设计到控制器的实现,再到视图层的展示,全面解析Spring MVC的核心功能与实现细节。 ... [详细]
  • 本文详细介绍了如何解决Uploadify插件在Internet Explorer(IE)9和10版本中遇到的点击失效及JQuery运行时错误问题。通过修改相关JavaScript代码,确保上传功能在不同浏览器环境中的一致性和稳定性。 ... [详细]
  • 本文介绍了如何使用PHP代码实现微信平台的媒体素材上传功能,详细解释了API接口的使用方法和注意事项,确保文件路径正确以避免常见的错误。 ... [详细]
  • 本文详细探讨了Laravel框架中的数据库操作,包括读写分离、事务处理、Eloquent ORM的使用、关联关系管理及性能优化技巧。 ... [详细]
  • 本文详细记录了《PHP与MySQL Web开发》第一章的学习心得,特别关注了PHP的基本构成元素、标记风格、编程注意事项及表单处理技巧等内容。 ... [详细]
  • ThinkPHP 文件缓存组件详解与应用
    本文深入探讨了ThinkPHP框架中的文件缓存类实现,提供了详细的代码示例和使用说明,旨在帮助开发者更好地理解和利用这一功能来优化应用程序性能。 ... [详细]
  • 本文探讨了PHP中使用命名空间和自动加载机制的重要性,特别是在大型项目中,如何有效管理和加载文件,避免代码冗余,提高开发效率。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 双向数据绑定技术使得对象属性与用户界面之间可以相互影响,即对象属性的更改能即时反映到界面上,同时用户的界面操作也能同步更新对象状态。本文将介绍如何利用简单的JavaScript代码实现这一功能。 ... [详细]
  • 每位开发者都应该拥有一个展示自我技能与分享知识的空间——个人技术博客。本文将指导你如何使用静态网站生成器Hexo结合GitHub Pages搭建这样一个平台。 ... [详细]
  • 本文探讨了如何在Django中创建一个能够根据需求选择不同模板的包含标签。通过自定义逻辑,开发者可以在多个模板选项中灵活切换,以适应不同的显示需求。 ... [详细]
  • VSCode中实现大型项目函数跳转的方法
    在处理大型代码项目时,简单的C/C++插件往往无法满足需求。本文介绍如何通过配置GNU Global等工具,在VSCode中实现高效的函数跳转。 ... [详细]
  • 本文介绍了如何利用snownlp库对微博内容进行情感分析,包括安装、基本使用以及如何自定义训练模型以提高分析准确性。 ... [详细]
author-avatar
吴燕凤怡雨家琴
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有