# 行为架构
* * * * *
### 行为介绍
行为(Behavior)是ThinkPHP扩展机制中比较关键的一项扩展,行为既可以独立调用,也可以绑定到某个标签中进行侦听,在官方提出的CBD模式中行为也占了主要的地位,可见行为在ThinkPHP框架中意义非凡。
这里指的行为是一个比较抽象的概念,你可以把行为想象成在应用执行过程中的一个动作或者处理。在框架的执行流程中,例如路由检测是一个行为,静态缓存是一个行为,用户权限检测也是行为,大到业务逻辑,小到浏览器检测、多语言检测等等都可以当做是一个行为,甚至说你希望给你的网站用户的第一次访问弹出Hello,world!这些都可以看成是一种行为,行为的存在让你无需改动框架和应用,而在外围通过扩展或者配置来改变或者增加一些功能。
而不同的行为之间也具有位置共同性,比如,有些行为的作用位置都是在应用执行前,有些行为都是在模板输出之后,我们把这些行为发生作用的位置称之为标签(位),当应用程序运行到这个标签的时候,就会被拦截下来,统一执行相关的行为,类似于AOP编程中的“切面”的概念,给某一个切面绑定相关行为就成了一种类AOP编程的思想。
这些是TP5官方文档中描述的概念,下面来看看OneBase中有哪些行为。
* * * * *
### OneBase中的行为
打开系统app目录下的tags.php,可以看到系统的行为定义。
~~~
<?php
// +---------------------------------------------------------------------+
// | OneBase | [ WE CAN DO IT JUST THINK ] |
// +---------------------------------------------------------------------+
// | Licensed | http://www.apache.org/licenses/LICENSE-2.0 ) |
// +---------------------------------------------------------------------+
// | Author | Bigotry <3162875@qq.com> |
// +---------------------------------------------------------------------+
// | Repository | https://gitee.com/Bigotry/OneBase |
// +---------------------------------------------------------------------+
// 行为目录路径
define('BEHAVIOR_PATH', 'app\\common\\behavior\\');
$data = [
// 应用初始化
'app_init' => [],
// 应用开始
'app_begin' => [],
// 模块初始化
'module_init' => [],
// 操作开始执行
'action_begin' => [],
// 视图内容过滤
'view_filter' => [],
// 日志写入
'log_write' => [],
// 应用结束
'app_end' => [],
];
// 若不为安装流程则初始化系统行为
if(BIND_MODULE != 'install') :
$data['app_init'] = [BEHAVIOR_PATH . 'InitBase', BEHAVIOR_PATH . 'InitHook'];
$data['app_begin'] = [BEHAVIOR_PATH . 'AppBegin'];
$data['app_end'] = [BEHAVIOR_PATH . 'AppEnd'];
endif;
return $data;
~~~
可以看到咱们OneBase使用了 3个行为标签位,分别是app_init,app_begin,app_end。
初始化的标签位执行了2个行为,OneBase中默认共4个行为。
下面来逐一讲解行为的作用
**初始化基础信息行为**
~~~
<?php
// +---------------------------------------------------------------------+
// | OneBase | [ WE CAN DO IT JUST THINK ] |
// +---------------------------------------------------------------------+
// | Licensed | http://www.apache.org/licenses/LICENSE-2.0 ) |
// +---------------------------------------------------------------------+
// | Author | Bigotry <3162875@qq.com> |
// +---------------------------------------------------------------------+
// | Repository | https://gitee.com/Bigotry/OneBase |
// +---------------------------------------------------------------------+
namespace app\common\behavior;
use think\Loader;
/**
* 初始化基础信息行为
*/
class InitBase
{
/**
* 初始化行为入口
*/
public function run()
{
// 初始化常量
$this->initConst();
// 初始化配置
$this->initConfig();
// 注册命名空间
$this->registerNamespace();
}
/**
* 初始化常量
*/
private function initConst()
{
// 初始化分层名称常量
$this->initLayerConst();
// 初始化结果常量
$this->initResultConst();
// 初始化数据状态常量
$this->initDataStatusConst();
// 初始化时间常量
$this->initTimeConst();
// 初始化系统常量
$this->initSystemConst();
// 初始化路径常量
$this->initPathConst();
// 初始化API常量
$this->initApiConst();
}
/**
* 初始化分层名称常量
*/
private function initLayerConst()
{
define('LAYER_LOGIC_NAME' , 'logic');
define('LAYER_MODEL_NAME' , 'model');
define('LAYER_SERVICE_NAME' , 'service');
define('LAYER_CONTROLLER_NAME' , 'controller');
define('LAYER_VALIDATE_NAME' , 'validate');
define('LAYER_VIEW_NAME' , 'view');
}
/**
* 初始化结果标识常量
*/
private function initResultConst()
{
define('RESULT_SUCCESS' , 'success');
define('RESULT_ERROR' , 'error');
define('RESULT_REDIRECT' , 'redirect');
define('RESULT_MESSAGE' , 'message');
define('RESULT_URL' , 'url');
define('RESULT_DATA' , 'data');
}
/**
* 初始化数据状态常量
*/
private function initDataStatusConst()
{
define('DATA_STATUS_NAME' , 'status');
define('DATA_NORMAL' , 1);
define('DATA_DISABLE' , 0);
define('DATA_DELETE' , -1);
define('DATA_SUCCESS' , 1);
define('DATA_ERROR' , 0);
}
/**
* 初始化API常量
*/
private function initApiConst()
{
define('API_CODE_NAME' , 'code');
define('API_MSG_NAME' , 'msg');
}
/**
* 初始化时间常量
*/
private function initTimeConst()
{
define('TIME_CT_NAME' , 'create_time');
define('TIME_UT_NAME' , 'update_time');
define('TIME_NOW' , time());
}
/**
* 初始化路径常量
*/
private function initPathConst()
{
define('PATH_ADDON' , ROOT_PATH . SYS_ADDON_DIR_NAME . DS);
define('PATH_PUBLIC' , ROOT_PATH . 'public' . DS);
define('PATH_UPLOAD' , PATH_PUBLIC . 'upload' . DS);
define('PATH_PICTURE' , PATH_UPLOAD . 'picture' . DS);
define('PATH_FILE' , PATH_UPLOAD . 'file' . DS);
define('PATH_SERVICE' , ROOT_PATH . DS . SYS_APP_NAMESPACE . DS . SYS_COMMON_DIR_NAME . DS . LAYER_SERVICE_NAME . DS);
define('PATH_COMMON_LOGIC' , SYS_APP_NAMESPACE . SYS_DS_CONS . SYS_COMMON_DIR_NAME . SYS_DS_CONS . LAYER_LOGIC_NAME . SYS_DS_CONS);
}
/**
* 初始化系统常量
*/
private function initSystemConst()
{
define('SYS_APP_NAMESPACE' , config('app_namespace'));
define('SYS_HOOK_DIR_NAME' , 'hook');
define('SYS_ADDON_DIR_NAME' , 'addon');
define('SYS_DRIVER_DIR_NAME' , 'driver');
define('SYS_COMMON_DIR_NAME' , 'common');
define('SYS_STATIC_DIR_NAME' , 'static');
define('SYS_VERSION' , '1.0.0');
define('SYS_ADMINISTRATOR_ID' , 1);
define('SYS_DS_PROS' , '/');
define('SYS_DS_CONS' , '\\');
$database_config = config('database');
define('SYS_DB_PREFIX' , $database_config['prefix']);
define('SYS_ENCRYPT_KEY' , $database_config['sys_data_key']);
}
/**
* 初始化配置信息
*/
private function initConfig()
{
$model = model(SYS_COMMON_DIR_NAME . SYS_DS_PROS . 'Config');
$config_list = $model->all();
foreach ($config_list as $info) : $config_array[$info['name']] = $info['value']; endforeach;
config($config_array);
$this->initTmconfig();
}
/**
* 初始化动态配置信息
*/
private function initTmconfig()
{
$list_rows = config('list_rows');
$api_key = config('api_key');
$jwt_key = config('jwt_key');
define('DB_LIST_ROWS' , empty($list_rows) ? 10 : $list_rows);
define('API_KEY' , empty($api_key) ? 'OneBase' : $api_key);
define('JWT_KEY' , empty($jwt_key) ? 'OneBase' : $jwt_key);
}
/**
* 注册命名空间
*/
private function registerNamespace()
{
// 注册插件根命名空间
Loader::addNamespace(SYS_ADDON_DIR_NAME, PATH_ADDON);
}
}
~~~
可以看到基本上都是一些常量的定义,就是初始化系统的常量。
另外初始化了系统的配置信息,此处的配置信息是入库的。
最后是注册命名空间。
初始化基础信息行为中基本上就做了这三件事情。
**初始化钩子信息行为**
~~~
<?php
// +---------------------------------------------------------------------+
// | OneBase | [ WE CAN DO IT JUST THINK ] |
// +---------------------------------------------------------------------+
// | Licensed | http://www.apache.org/licenses/LICENSE-2.0 ) |
// +---------------------------------------------------------------------+
// | Author | Bigotry <3162875@qq.com> |
// +---------------------------------------------------------------------+
// | Repository | https://gitee.com/Bigotry/OneBase |
// +---------------------------------------------------------------------+
namespace app\common\behavior;
use think\Hook;
/**
* 初始化钩子信息行为
*/
class InitHook
{
/**
* 行为入口
*/
public function run()
{
$hook = model(SYS_COMMON_DIR_NAME . SYS_DS_PROS . ucwords(SYS_HOOK_DIR_NAME));
$list = $hook->column('id,name,addon_list');
foreach ($list as $v) : $addon_list[$v['name']] = get_addon_class($v['addon_list']); endforeach;
Hook::import($addon_list);
}
}
~~~
此行为就是将数据库中的钩子查询出来与插件关联,并导入到系统中对系统提供面向切面的扩展方式。
**应用开始与结束行为**
~~~
<?php
// +---------------------------------------------------------------------+
// | OneBase | [ WE CAN DO IT JUST THINK ] |
// +---------------------------------------------------------------------+
// | Licensed | http://www.apache.org/licenses/LICENSE-2.0 ) |
// +---------------------------------------------------------------------+
// | Author | Bigotry <3162875@qq.com> |
// +---------------------------------------------------------------------+
// | Repository | https://gitee.com/Bigotry/OneBase |
// +---------------------------------------------------------------------+
namespace app\common\behavior;
/**
* 应用开始行为
*/
class AppBegin
{
/**
* 行为入口
*/
public function run()
{
debug('app_begin');
}
}
~~~
~~~
<?php
// +---------------------------------------------------------------------+
// | OneBase | [ WE CAN DO IT JUST THINK ] |
// +---------------------------------------------------------------------+
// | Licensed | http://www.apache.org/licenses/LICENSE-2.0 ) |
// +---------------------------------------------------------------------+
// | Author | Bigotry <3162875@qq.com> |
// +---------------------------------------------------------------------+
// | Repository | https://gitee.com/Bigotry/OneBase |
// +---------------------------------------------------------------------+
namespace app\common\behavior;
/**
* 应用结束行为
*/
class AppEnd
{
/**
* 行为入口
*/
public function run()
{
debug('app_end');
write_exe_log('app_begin', 'app_end');
}
}
~~~
可以看到在开始行为里面就是debug('app_begin');这个函数的调用,这个函数是TP提供用于调试的函数,用于记录执行时间与内存消耗等。
在结束行为中执行了 debug('app_end'); 用于标记结束的位置。
系统结束行为中会执行 write_exe_log 函数,这个函数是OneBase中封装的,用于记录系统的执行记录,若数据库配置 is_write_exe_log 为启用则会对每次系统操作进行执行记录写入,若为禁用则函数会返回false,跳过后续的记录逻辑。
默认是关闭记录,考虑到有些用户对OneBase不熟悉 导致记录过大 影响系统执行效率。
- 序言
- 基础
- 安装环境
- 安装演示
- 规范
- 目录
- 介绍
- 后台介绍
- 后台首页
- 会员管理
- 系统管理
- 系统设置与配置管理
- 菜单管理
- 系统回收站
- 服务管理
- 插件管理
- 文章管理
- 接口管理
- 优化维护
- SEO管理
- 数据库
- 文件清理
- 行为日志
- 执行记录
- 统计分析
- 接口介绍
- 接口文档
- 错误码设计
- Token介绍
- 前台介绍
- 架构
- 架构总览
- 生命周期
- 入口文件
- 模块设计
- 依赖注入
- 控制器架构
- 逻辑架构
- 验证架构
- 服务架构
- 模型架构
- 行为架构
- 插件架构
- 配置
- 配置介绍
- 配置加载
- 配置扩展
- 请求
- 请求信息
- 日志
- 后台行为日志
- 系统执行日志
- 框架日志
- 数据
- 数据库设计
- 数据字典
- 数据库操作
- 事务控制
- 混合操作
- 实战
- 控制器
- 逻辑与验证
- 视图与模型
- 插件研发
- 服务研发
- 接口研发
- 杂项
- 数据导入导出
- 二维码条形码
- 邮件发送
- 云存储服务
- 支付服务
- 短信服务
- 微信分享
- 生成海报
- 聊天室
- PJAX
- Demo
- Widget
- 附录
- 常量参考
- 配置参考
- 函数参考
- 进阶
- Redis
- 自动缓存
- 全自动缓存
- 索引
- 数据签名
- 全自动事务
- 队列