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

ThinkPHP3.1快速入门(22)行为

行为(Behavior)是ThinkPHP扩展机制中比较关键的一项扩展,行为既可以独立调用,也可以绑定到某个标签中进行侦听,官方提出的CBD模式中行为也占了主要的地位,可见行为在ThinkPHP框架中意义非凡。

概述

行为(Behavior)是ThinkPHP扩展机制中比较关键的一项扩展,行为既可以独立调用,也可以绑定到某个标签中进行侦听,官方提出的CBD模式中行为也占了主要的地位,可见行为在ThinkPHP框架中意义非凡。
这里指的行为是一个比较抽象的概念,你可以想象成在应用执行过程中的一个动作或者处理,在框架的执行流程中,各个位置都可以有行为产生,例如路由检测是一个行为,静态缓存是一个行为,用户权限检测也是行为,大到业务逻辑,小到浏览器检测、多语言检测等等都可以当做是一个行为,甚至说你希望给你的网站用户的第一次访问弹出Hello,world!这些都可以看成是一种行为,行为的存在让你无需改动框架和应用,而在外围通过扩展或者配置来改变或者增加一些功能。
而不同的行为之间也具有位置共同性,比如,有些行为的作用位置都是在应用执行前,有些行为都是在模板输出之后,我们把这些行为发生作用的位置称之为标签(位),当应用程序运行到这个标签的时候,就会被拦截下来,统一执行相关的行为,类似于AOP编程中的“切面”的概念,给某一个切面绑定相关行为就成了一种类AOP编程的思想。

系统标签位

系统核心提供的标签位置包括下面几个(按照执行顺序排列):
app_init 应用初始化标签位
path_info PATH_INFO检测标签位
route_check 路由检测标签位
app_begin 应用开始标签位
action_name 操作方法名标签位
action_begin 控制器开始标签位
view_begin 视图输出开始标签位
view_template 视图模板解析标签位
view_parse 视图解析标签位
view_filter 视图输出过滤标签位
view_end 视图输出结束标签位
action_end 控制器结束标签位
app_end 应用结束标签位
在每个标签位置,可以配置多个行为定义,行为的执行顺序按照定义的顺序依次执行。除非前面的行为里面中断执行了(某些行为可能需要中断执行,例如检测机器人或者非法执行行为),否则会继续下一个行为的执行。
除了这些系统内置标签之外,开发人员还可以在应用中添加自己的应用标签,例如我们给应用的公共Action类CommonAction添加一个action_init标签位。
  1. Class CommonAction extends Action{
  2.     Public function _initialize(){
  3.         tag('action_init'); // 添加action_init 标签
  4.     }
  5. }
注意:tag函数用于设置某个标签位,可以传入并且只接受一个参数,如果需要传入多个参数,请使用数组,该参数为引用传值,所以只能传入变量。

核心行为

新版系统的很多核心功能也是采用行为扩展组装的,虽然在开发过程中可能感觉不到这种变化,但正是由于这种架构设计的改变,让新版变得更加灵活和易扩展,这是一个里程碑式的改变,对于满足项目日益纷繁复杂的需求和定制底层框架提供了更多的方便和可能性。
框架核心内置的行为包括如下:
行为名称 说明 对应标签位置
checkRoute 路由检测行为,完成内置的路由功能 route_check
LocationTemplate 模板定位行为,完成模板文件自动定位和输出规则 view_template
ParseTemplate 模板文件解析,并支持第三方模板引擎驱动 view_parse
ShowPageTrace 页面Trace功能行为,完成页面Trace功能 view_end
ShowRuntime 运行时间显示行为,完成运行时间显示 view_filter
TokenBuild 令牌生成行为,完成表单令牌的自动生成 view_filter
ReadHtmlCache 读取静态缓存行为 app_init
WriteHtmlCache 生成静态缓存行为 view_filter

行为定义

行为类的命名采用:行为名称(驼峰法,首字母大写)+Behavior 行为类的定义方式如下:
  1. class TestBehavior extends Behavior {
  2.         // 行为参数定义
  3.         protected $options   =  array(
  4.             'test_param'        => false,   //  行为参数 会转换成TEST_PARAM配置参数
  5.         );
  6.         // 行为扩展的执行入口必须是run
  7.         public function run(&$params){
  8.             if(C('TEST_PARAM')) {
  9.                 echo 'RUNTEST BEHAVIOR '.$params;
  10.             }
  11.         }
  12. }
行为类必须继承Behavior类,并且必须定义执行入口方法run(&$params); 由于行为的调用机制影响,run方法不需要任何返回值,所有返回都通过引用返回。每个行为类可以定义options属性,该属性中的参数会自动转换成单独配置参数,也就是说该参数可以用全局的C方法直接读取或者修改,同时也意味着行为中定义的options参数只是提供一个默认值,你完全可以在配置文件中或者使用C方法动态配置生效,而不需要手动传入行为类。这是Behavior类提供的方便和全局配置对接的一个特性,当然你完全可以不依赖这个特性。
因此,上面的run方法实现也可以更改为:
  1.         public function run(&$params){
  2.             if($this->test_param) {
  3.                 echo 'RUNTEST BEHAVIOR '.$params;
  4.             }
  5.         }
run方法的参数只有一个,但支持传入数组。
行为类是支持自动加载的,其放置的位置可以包括如下位置,可以根据需要自行选择:
位置 所在目录 说明
核心行为目录 ThinkPHP/Lib/Behavior/ 通常用于放置一些核心的内置行为
扩展行为目录 Extend/Behavior/ 这是ThinkPHP扩展的行为扩展目录,第三方的扩展大都在此
项目的行为目录 项目目录/Lib/Behavior/ 用于项目自身的行为扩展
独立分组的行为目录 独立分组目录/Behavior/ 如果采用了独立分组的话,也可以把行为类放在这里
官方扩展包的行为扩展都位于Extend/Behavior/目录下面。

行为绑定

行为定义完成后,就需要绑定到某个标签位置才能生效,否则是不会执行的。
我们需要在项目的行为定义文件tags.php文件中进行行为和标签的位置定义,格式如下:
  1.     return array(
  2.         '标签名称'=>array('行为名1','行为名2',...), 
  3.     );
标签名称包括我们前面列出的系统标签和应用中自己定义的标签名称,比如你需要在app_init标签位置定义一个CheckLangBehavior行为类的话,可以使用:
  1. return array(
  2.      'app_init'=>array('CheckLang'),
  3. );
可以给一个标签位定义多个行为,行为的执行顺序就是定义的先后顺序,例如:
  1. return array(
  2.      'app_init'=>array('CheckLang','CronRun'),
  3. );
默认情况下tags.php中定义的行为会并入系统行为一起执行,也就是说如果系统的行为定义中app_init标签中已经定义了其他行为,则会首先执行系统行为扩展中定义的行为,然后再执行项目行为中定义的行为,如果你希望项目tags中定义的行为完全替换系统的行为扩展,可以使用:
  1. return array(
  2.      'app_init'=>array('CheckLang','CronRun','_overlay'=>1),
  3. );
应用行为的定义没有限制,你可以把一个行为绑定到多个标签位置执行,例如:
  1.     return array(
  2.         'app_begin'=>array('Test'), // 在app_begin 标签位添加Test行为
  3.         'app_end'=>array('Test'), // 在app_end 标签位添加Test行为
  4.     );
为了避免混淆,自定义的行为扩展尽量不要和核心的行为扩展重名。
除了定义tags行为配置文件之外,框架还提供了动态添加行为到标签位的方法,例如我们可以使用下面的方式添加Test行为到app_end标签位,而无需在tags文件中添加定义:
  1. add_tag_behavior'app_end','Test');
表示把Test行为添加到app_end标签位的最后,你可以把这个代码放到项目的公共函数文件中甚至直接放到行为类的最后(如果你确定这个行为扩展只有你的项目会用到的话)。

单独执行

有时候,行为的调用不一定要放到标签才能调用,如果需要的话,我们可以在控制器中直接调用行为。例如,我们可以把用户权限检测封装成一个行为类,例如:
  1. class AuthCheckBehavior extends Behavior {
  2.     // 行为参数定义
  3.     protected $options   =  array(
  4.     'USER_AUTH_ON'        =>false,   //  是否开启用户认证
  5.     'USER_AUTH_ID'        => 'user_id',   //  定义用户的id为权限认证字段
  6.     );
  7.     // 行为扩展的执行入口必须是run
  8.     public function run(&$return){
  9.         if(C('USER_AUTH_ON ')) {
  10.             // 进行权限认证逻辑 如果认证通过 $return = true;
  11.             // 否则用halt输出错误信息
  12.         }
  13.     }
定义了AuthCheck行为后,然后在_initialize方法中直接用下面的方式调用:
  1. B('AuthCheck');
注意:因为这种方式的行为调用需要在相关位置添加代码,所以一般只有在应用代码才直接使用B方法调用。

总结

说了这么多,只是让你了解ThinkPHP中的行为的概念和运行机制,至于如何用好行为,以及怎么封装行为和定义标签还需要多实践了。相信很多熟悉ThinkPHP的开发者一定可以通过行为扩展来更方便的给框架增加功能了。

推荐阅读
  • 探索AI智能机器人自动盈利系统的构建
    用户可通过支付198元押金及30元设备维护费租赁AI智能机器人,推荐他人加入可获得相应佣金。随着推荐人数的增加,用户将逐步解锁更高版本,享受更多收益。 ... [详细]
  • 本文探讨了在一个物理隔离的环境中构建数据交换平台所面临的挑战,包括但不限于数据加密、传输监控及确保文件交换的安全性和可靠性。同时,作者结合自身项目经验,分享了项目规划、实施过程中的关键决策及其背后的思考。 ... [详细]
  • Bootstrap Paginator 分页插件详解与应用
    本文深入探讨了Bootstrap Paginator这款流行的JavaScript分页插件,提供了详细的使用指南和示例代码,旨在帮助开发者更好地理解和利用该工具进行高效的数据展示。 ... [详细]
  • 本文介绍了在一卡通项目中设计加密管理方案时,证书服务器的配置步骤及其在用户权限控制中的应用。首先概述了证书服务器的基本设置,包括操作系统的选择和证书服务的安装,随后详细描述了服务器证书及客户端证书的创建过程。 ... [详细]
  • CGroups: 资源管理和控制
    CGroups(Control Groups)是Linux内核提供的一个功能,旨在限制、记录和隔离进程组使用的物理资源,如CPU、内存和I/O等。它通过精细的资源管理,支持现代容器技术如Docker的资源限制需求。 ... [详细]
  • 深入解析Java中的锁类型及其应用场景
    本文详细介绍了Java中常见的锁类型,包括乐观锁与悲观锁、独占锁与共享锁、互斥锁与读写锁、可重入锁、公平锁与非公平锁、分段锁、偏向锁、轻量级锁、重量级锁以及自旋锁。每种锁的特性、作用及适用场景均有所涉及。 ... [详细]
  • 本文探讨了HDU 4035的问题,涉及一个由n个房间组成的迷宫,这些房间通过n-1条隧道相互连接,形成一棵树结构。任务是从起点1号房间出发,计算到达出口所需经过的平均隧道数量,考虑了在每个房间中可能发生的三种情况及其相应概率。 ... [详细]
  • 一、数据更新操作DML语法中主要包括两个内容:查询与更新,更新主要包括:增加数据、修改数据、删除数据。其中这些操作是离不开查询的。1、增加数据语法:INSERTINTO表名称[(字 ... [详细]
  • 远程访问用户 Kindle通过电子书实现控制
    介绍自2007年以来,亚马逊已售出数千万台Kindle,令人印象深刻。但这也意味着数以千万计的人可能会因为这些Kindle中的软件漏洞而被黑客入侵。他 ... [详细]
  • Android开发经验分享:优化用户体验的关键因素
    随着Android市场的不断扩展,用户对于移动应用的期望也在不断提高。本文探讨了在Android开发中如何优化用户体验,以及为何用户体验的重要性超过了技术本身。 ... [详细]
  • Python 领跑!2019年2月编程语言排名更新
    根据最新的编程语言流行指数(PYPL)排行榜,Python 在2019年2月的份额达到了26.42%,稳坐榜首位置。 ... [详细]
  • 深入解析Dubbo:使用与源码分析
    本文详细介绍了Dubbo的使用方法和源码分析,涵盖其架构设计、核心特性和调用流程。 ... [详细]
  • ABP框架是ASP.NET Boilerplate的简称,它不仅是一个开源且文档丰富的应用程序框架,还提供了一套基于领域驱动设计(DDD)的最佳实践架构模型。本文将详细介绍ABP框架的特点、项目结构及其在Web API优先架构中的应用。 ... [详细]
  • 开发笔记:前端之前端初识
    开发笔记:前端之前端初识 ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
author-avatar
-MP5
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有