ThinkPHP5.1學習筆記 - 行爲

一、簡介

你可以把行爲理解成是“在程序執行過程中的某一個位置會調起一個或一類事件”的動作。行爲發生作用的位置我們稱之爲鉤子,當應用程序運行到這個鉤子的時候,就會被攔截下來,統一執行相關的行爲。

類似於AOP編程中的“切面”的概念,給某一個鉤子綁定相關行爲就成了一種類AOP編程的思想。

一個完整的行爲事件包括以下三項:
1)行爲定義
2)行爲綁定
3)監聽鉤子

ThinkPHP關於行爲的核心方法都定義於核心文件thinkphp\library\think\Hook.php中。

二、行爲定義

行爲類一般放置於模塊目錄下的behavior目錄裏,當然這不是硬性要求,你也可以按照你的喜好自定義目錄。

行爲類的定義很簡單,一般來說只需要定義一個行爲入口方法run即可。如,我需要給我的後臺管理系統做一個用戶登錄行爲檢測:

namespace app\admin\behavior;

/**
 * Test: Use to learn ThinkPHP-Hook.
 *
 * Email: [email protected]
 * Author: Chan
 */
class MyHook
{
    public function run($params){
        echo '<b>自定義鉤子的行爲</b>';
    }

}

行爲的入口方法名稱支持自定義,如果需要更改在應用公共文件(common.php)中添加下面的代碼即可:

Hook::portal('portal');

一個鉤子可以註冊多個行爲,執行到某個鉤子位置後,會按照註冊的順序依次執行相關的行爲。但在某些特殊的情況下,你可以設置某個鉤子只能執行一次行爲,又或者你可以在一個鉤子的某個行爲中返回false來強制終止後續的行爲執行;一個行爲可以同時註冊到多個不同的鉤子上,完全看應用的需求來設計。

可以在行爲方法中使用依賴注入,例如:

namespace app\index\behavior;

use think\Request;

class Test 
{
    public function run(Request $request, $params)
    {
        // 行爲邏輯
    }
}

三、行爲綁定

行爲定義完成後,就需要綁定到某個標籤位置(鉤子)才能生效,否則是不會執行的。

1、通過配置文件

我們可以直接在應用目錄下面或者模塊的目錄下面定義tags.php文件來統一定義行爲,定義格式如下:

// 應用行爲擴展定義文件
return [
    // 模塊初始化
    'module_init'  => ['app\\admin\\behavior\\Login'],
    // 操作開始執行
    'action_begin' => [],
    // 視圖內容過濾
    'view_filter'  => [],
    // 日誌寫入
    'log_write'    => [],
    // 應用結束
    'app_end'      => [],

    //自定義鉤子  =>   綁定相應的行爲
    'my_hook'      => ['app\\admin\\behavior\\MyHook'],
];

2、使用think\facade\Hook類的add方法註冊行爲

Hook::add('my_hook','app\\admin\\behavior\\MyHook');

注意:
1)Hook::add要執行在Hook::listen之前,否則不會綁定成功。
2)Hook::add要麼調用run方法要麼調用當前鉤子名稱(駝峯法)的方法。

如果需要使用Hook::add調用其它方法,可以定義靜態方法(app\index\behavior\CheckAuth::hello)或者使用閉包。

四、監聽鉤子

鉤子的位置必須是事先設計好的,無論是框架還是應用的,要設置一個鉤子,只需要在相關的位置添加一行代碼(事先需要引入think\facade\Hook類),語法如下:

Hook::listen('鉤子名稱','參數','是否只有一次有效返回值');

1、系統鉤子
系統鉤子就是框架已經默認設置好的,開發者可以直接使用。

鉤子 描述 參數
app_init 應用初始化標籤位
app_dispatch 應用調度標籤位
app_begin 應用開始標籤位
module_init 模塊初始化標籤位
action_begin 控制器開始標籤位 當前的callback參數
view_filter 視圖輸出過濾標籤位 當前模板渲染輸出內容
app_end 應用結束標籤位 當前響應對象實例
log_write 日誌write方法標籤位 當前寫入的日誌信息
log_level 日誌寫入標籤位 包含日誌類型和日誌信息的數組(V5.1.25+)
response_send 響應發送標籤位 當前響應對象
response_end 輸出結束標籤位 當前響應對象實例

2、自定義鉤子

use think\facade\Hook;

Hook::listen('module_init'); //監聽系統鉤子 module_init
Hook::listen('my_hook'); //監聽自定位鉤子 my_hook

五、閉包支持

可以不用定義行爲直接把閉包函數綁定到某個標籤位,例如:

Hook::add('hook_function',function($params){
    var_dump($params);
});
Hook::listen('hook_function','Hi nosee!');

六、直接執行行爲

如果需要,你也可以不綁定行爲標籤,直接調用某個行爲,使用:

// 執行 app\index\behavior\CheckAuth行爲類的run方法 並引用傳入params參數
$result = Hook::exec('app\\index\\behavior\\CheckAuth',$params);

直接執行行爲的時候,執行的是run方法,如果需要執行行爲類的其它方法,可以使用

// 執行 app\index\behavior\CheckAuth行爲類的hello方法 並引用傳入params參數
$result = Hook::exec(['app\\index\\behavior\\CheckAuth','hello'], $params);

參考

官方手冊:https://www.kancloud.cn/manual/thinkphp5_1/354129

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章