# 行為架構
* * * * *
### 行為介紹
行為(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
- 自動緩存
- 全自動緩存
- 索引
- 數據簽名
- 全自動事務
- 隊列