13.1 行为扩展
匿名 · 更新于 2013/12/26
行为和标签
行为在新版ThinkPHP的架构里面起着举足轻重的作用,在系统核心之上,设置了很多标签扩展位,而每个标签位置可以依次执行各自的独立行为。行为扩展就因此而诞生了,而且很多系统功能也是通过内置的行为扩展完成的,所有行为扩展都是可替换和增加的,由此形成了底层框架可组装的基础。系统核心提供的标签位置包括下面几个(按照执行顺序排列):
| 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标签位。
Class CommonAction extends Action{Public function _initialize(){tag('action_init'); // 添加action_init 标签}}
3
内置行为
新版系统的很多核心功能也是采用行为扩展组装的,虽然在开发过程中可能感觉不到这种变化,但正是由于这种架构设计的改变,让新版变得更加灵活和易扩展,这是一个里程碑式的改变,对于满足项目日益纷繁复杂的需求和定制底层框架提供了更多的方便和可能性。内置的行为包括下面:
| 行为名称 | 说明 | 对应标签位置 |
|---|---|---|
| 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即可,类的命名规范是:行为名称+Behavior
行为的执行入口方法是run方法,因此行为类只需要run方法具备public访问权限,入口方法只支持一个参数(可以用数组),并且采用引用方式传参,因此不需要任何返回值。每个行为可以定义options属性,该属性中的参数会自动转换成单独配置参数,下面是一个示例:
class TestBehavior extends Behavior {// 行为参数定义protected $options = array('TEST_PARAM' => false, // 行为参数 会转换成TEST_PARAM配置参数);// 行为扩展的执行入口必须是runpublic function run(&$params){if(C('TEST_PARAM')) {echo 'RUNTEST BEHAVIOR '.$params;}}
C('TEST_PARAM ')
'TEST_PARAM' =>true
1
行为调用
定义了一个行为扩展之后,系统提供了三种方式可以调用行为:一、添加到行为配置文件
为了执行Test行为,我们在这里把Test行为加入app_end 标签位置,在项目配置目录中添加tags.php文件,在其中添加下面代码:
return array('app_end'=>array('Test'), // 在app_end 标签位添加Test行为);
return array('action_init'=>array('Test'), // 在action_init 标签位添加Test行为);
return array('app_begin'=>array('Test'), // 在app_begin 标签位添加Test行为'app_end'=>array('Test'), // 在app_end 标签位添加Test行为);
return array('app_end'=>array('Test','_overlay'=>1),);
二、函数方式动态定义
除了定义tags行为配置文件之外,系统还提供了动态添加行为到标签位的方法,例如我们可以使用下面的方式添加Test行为到app_end标签位,而无需在tags文件中添加定义:
add_tag_behavior('app_end','Test');
表示把Test行为添加到app_end标签位的最后,你可以把这个代码放到项目的公共函数文件中甚至直接放到行为类的最后(如果你确定这个行为扩展只有你的项目会用到的话)。
应用行为扩展类除了放到项目类库的Behavior目录外, 还可以放到系统的行为扩展目录Extend/Behavior/,行为类在执行过程中会自动加载。
三、不放入标签直接执行
有时候,行为的调用不一定要放到标签才能调用,如果需要的话,我们可以在控制器中直接调用行为。例如,我们可以把用户权限检测封装成一个行为类,例如:
class AuthCheckBehavior extends Behavior {// 行为参数定义protected $options = array('USER_AUTH_ON' =>false, // 是否开启用户认证'USER_AUTH_ID' => 'user_id', // 定义用户的id为权限认证字段);// 行为扩展的执行入口必须是runpublic function run(&$return){if(C('USER_AUTH_ON ')) {// 进行权限认证逻辑 如果认证通过 $return = true;// 否则用halt输出错误信息}}
B('AuthCheck');
注意:因为这种方式的行为调用需要在相关位置添加代码,所以一般只有在应用代码才直接使用B方法调用。
