thinkphp3 行为(behavior)分析和基本使用
1. 名词解析
官方解析: 来自 http://document.thinkphp.cn/manual_3_2.html#behavior_extend
行为(Behavior)是一个比较抽象的概念,你可以想象成在应用执行过程中的一个动作或者处理,在框架的执行流程中,各个位置都可以有行为产生,例如路由检测是一个行为,静态缓存是一个行为,用户权限检测也是行为,大到业务逻辑,小到浏览器检测、多语言检测等等都可以当做是一个行为,
甚至说你希望给你的网站用户的第一次访问弹出Hello,world!这些都可以看成是一种行为,行为的存在让你无需改动框架和应用,而在外围通过扩展或者配置来改变或者增加一些功能。 而不同的行为之间也具有位置共同性,比如,有些行为的作用位置都是在应用执行前,有些行为都是在模板输出之后,我们把这些行为发生作用的位置称之为标签(位),当应用程序运行到这个标签的时候,就会被拦截下来,统一执行相关的行为,
类似于AOP编程中的“切面”的概念,给某一个切面绑定相关行为就成了一种类AOP编程的思想。
1. 1 标签位置
1) 系统核心提供的标签位置包括下面几个(按照执行顺序排列):
app_init 应用初始化标签位 path_info PATH_INFO检测标签位 app_begin 应用开始标签位 action_name 操作方法名标签位 action_begin 控制器开始标签位 view_begin 视图输出开始标签位 view_parse 视图解析标签位 template_filter 模板内容解析标签位 view_filter 视图输出过滤标签位 view_end 视图输出结束标签位 action_end 控制器结束标签位 app_end 应用结束标签位
2) 自定义
行为定义: 通过{Common,Module}\Conf\tags.php配置文件定义,格式如下:
<?php return array( 'action_begin'=>array('Home\\Behaviors\\test','Home\\Behaviors\\test1'),//一个标签位可以有多个行为,使用数组即可。 // 如果是3.2.1以上版本 则需要改成 'action_begin'=>array('Home\\Behaviors\\testBehavior','Home\\Behaviors\\test1Behavior') );
开发人员还可以在应用中添加自己的应用标签。
比如在控制器的_initialize方法中:
\Think\Hook::add('action_begin','Home\\Behaviors\\test1');//同时添加多个行为,只要将第二个参数换成数组即可。 // 3.2.1以上版本 需要改成 // \Think\Hook::add('action_begin','Home\\Behaviors\\test1Behavior');
1.2 触发
行为的触发: 只要在合适的地方通过以下代码
\Think\Hook::listen('标签名'[,参数]); // 或者 // tag('标签名'[,参数]);
2. 使用场景
参考 1. 我们已经知道 行为 是类AOP编程的思想。除业务之外的操作,均可加入行为。比如日志,统计等。
3. 使用案例
3.1 全局或者模块登录校验
修改 tags.php
return [ // 应用初始化 'app_init' => [], // 应用开始 'app_begin' => [ "Collection\Behavior\TestBehavior" ], // 模块初始化 'module_init' => [], // 操作开始执行 'action_begin' => [ "\Behavior\AuthBehavior" ], // 视图内容过滤 'view_filter' => [], // 日志写入 'log_write' => [], // 应用结束 'app_end' => [], ];
Collection 是模块目录, Application/Collection/Behavior/TestBehavior 记录访问日志
<?php namespace Collection\Behavior; use Think/Log; class TestBehavior { public function run() { Log::write("有人访问"); } }
ThinkPHP\Library\Behavior\AuthBehavior 操作认证
<?php namespace Behavior; class AuthBehavior { public function run() { $session_id = basename(strtolower(__MODULE__).'_admin_id'); $authAdminId = session($session_id); $login_url = __MODULE__ . '/Public/login'; preg_match("/(login|createVerify)/i", $_SERVER["REQUEST_URI"],$matches); $is_login = ($matches && count($matches) > 0) ? true : false; $is_get = ($_SERVER['REQUEST_METHOD'] == 'GET') ? true : false; // var_dump($authAdminId, $is_get, $is_login);exit; if (!$authAdminId && (!$is_login && $is_get)) { $timestamp = I('get._'); if ($timestamp) { // ajax echo bjuiAjaxReturn(301, '请您先登录', '', '', '', true); exit; } else { // // $this->error('请您先登录', __MODULE__ . '/Public/login'); header('Content-type:text/html;charset=utf-8'); redirect($login_url, 2, '请您先登录'); } } } }
------ 未完待续 ------