下面由thinkphp教程欄目給大家介紹一個(gè)Thinkphp Hook行為的使用案例,希望對(duì)需要的朋友有所幫助!
thinkphp Hook行為的使用案例
行為,官方是如下介紹: 行為(Behavior)是ThinkPHP擴(kuò)展機(jī)制中比較關(guān)鍵的一項(xiàng)擴(kuò)展,行為既可以獨(dú)立調(diào)用,也可以綁定到某個(gè)標(biāo)簽中進(jìn)行偵聽(tīng),在官方提出的CBD模式中行為也占了主要的地位,可見(jiàn)行為在ThinkPHP框架中意義非凡。
這里指的行為是一個(gè)比較抽象的概念,你可以把行為想象成在應(yīng)用執(zhí)行過(guò)程中的一個(gè)動(dòng)作或者處理。
在框架的執(zhí)行流程中,例如路由檢測(cè)是一個(gè)行為,靜態(tài)緩存是一個(gè)行為,用戶(hù)權(quán)限檢測(cè)也是行為,大到業(yè)務(wù)邏輯,小到瀏覽器檢測(cè)、多語(yǔ)言檢測(cè)等等都可以當(dāng)做是一個(gè)行為,甚至說(shuō)你希望給你的網(wǎng)站用戶(hù)的第一次訪問(wèn)彈出Hello,world!這些都可以看成是一種行為,行為的存在讓你無(wú)需改動(dòng)框架和應(yīng)用,而在外圍通過(guò)擴(kuò)展或者配置來(lái)改變或者增加一些功能。
而不同的行為之間也具有位置共同性,比如,有些行為的作用位置都是在應(yīng)用執(zhí)行前,有些行為都是在模板輸出之后,我們把這些行為發(fā)生作用的位置稱(chēng)之為標(biāo)簽(位),當(dāng)應(yīng)用程序運(yùn)行到這個(gè)標(biāo)簽的時(shí)候,就會(huì)被攔截下來(lái),統(tǒng)一執(zhí)行相關(guān)的行為,類(lèi)似于AOP編程中的“切面”的概念,給某一個(gè)切面綁定相關(guān)行為就成了一種類(lèi)AOP編程的思想。
使用
行為的定義很簡(jiǎn)單,只是在某些場(chǎng)景下的應(yīng)用,可能有點(diǎn)難以理解。 在 laravel 中, 類(lèi)似于其事件監(jiān)聽(tīng)器, 當(dāng)觸發(fā)了某一行為進(jìn)行自動(dòng)觸發(fā)相關(guān)的操作方法
舉個(gè)例子來(lái)說(shuō)
一個(gè)登錄的功能,前期我們只需要校驗(yàn)密碼即可,按照以往的方法可以這樣做
function checkLogin() { $this->checkPass(); // -- 新增加的功能 $this->checkMobile(); $this->checkCaptcha(); //... 等等 echo '登錄成功'; }
在如上操作中,是不是很麻煩,針對(duì)一個(gè)登錄行為, 如果后期功能的增加我們需要不斷的去增加功能就必須得去修改控制器代碼
我們進(jìn)行解耦該怎么做呢?
即將行為,邏輯(鉤子)分離開(kāi), 讓代碼更加易于管理
使用如下,我們直接上圖
如上,我們定義了三個(gè)不同的即將發(fā)生的行為, 分別為連接網(wǎng)絡(luò) 、 關(guān)閉電腦、使用電腦
// Connect.php namespace appindexbehavior; class Connect { public function run() { echo '連接網(wǎng)絡(luò)'; } public function __destruct() { echo '<br/>'; } } // End.php namespace appindexbehavior; class End { public function run() { echo '關(guān)閉電腦'; echo '<br/>'; } } // On.php namespace appindexbehavior; class On { public function run() { echo '開(kāi)啟電腦'; echo '<br/>'; } public function qq() { echo '打開(kāi)QQ'; echo '<br/>'; } public function opBrowser() { echo '打開(kāi)瀏覽器'; echo '<br/>'; } public function app_end(&$param) { $param = '結(jié)束了'; } }
控制器文件 Index.php
namespace appindexcontroller; use thinkHook; class Index { public function __construct() { // 開(kāi)始綁定使用電腦需要進(jìn)行的操作 Hook::add('app_init', [ 'app\index\behavior\On', 'app\index\behavior\Connect', ] ); // 批量綁定 Hook::add('qq', 'app\index\behavior\On'); // 自定義標(biāo)簽名 Hook::add('opBrowser', 'app\index\behavior\On'); // 自定義標(biāo)簽名 // Hook::add('app_end', 'app\index\behavior\End'); // 系統(tǒng)標(biāo)簽位,無(wú)需綁定,自動(dòng)執(zhí)行 } public function index() { echo '我現(xiàn)在需要使用電腦進(jìn)行社交'; echo '<br/>'; Hook::listen('app_init'); // 手動(dòng)初始化 Hook::listen('qq'); // 打開(kāi)qq Hook::listen('opBrowser'); // 打開(kāi)瀏覽器 } }
輸出結(jié)果
1) 解析
首先,我們可以在一個(gè)全局中,例如控制器初始化中可以使用 Hook::add 開(kāi)始進(jìn)行綁定, 綁定完成后就可以使用 Hook::listen() 執(zhí)行相關(guān)綁定的方法,盡量不要使用Listen音譯去理解這個(gè)方法
他實(shí)際上不算監(jiān)聽(tīng),實(shí)際上是運(yùn)行的意思, 當(dāng)Listen的時(shí)候,會(huì)執(zhí)行相關(guān)在前面綁定的方法, 例如 Hook::listen('app_init') 后便會(huì)執(zhí)行 'app\index\behavior\On', 'app\index\behavior\Connect'
中的 run 方法
如果 執(zhí)行的行為標(biāo)簽 app_init 非系統(tǒng)標(biāo)簽或者在 app\index\behavior\On 中有 app_init 方法,則會(huì)就會(huì)執(zhí)行其中app_init的方法,而不是執(zhí)行run
2) 自定義標(biāo)簽
使用自定義標(biāo)簽必須滿(mǎn)足兩個(gè)條件, 1、Hook::add('qq') 對(duì)自定義標(biāo)簽 qq 進(jìn)行綁定了, 2、對(duì)應(yīng)的行為類(lèi)中必須存在 qq 這個(gè)方法, 否則自動(dòng)運(yùn)行 run 方法
3) tags.php 行為綁定
// ..tags.php <?php return [ 'app_init'=> [ 'app\index\behavior\On', 'app\index\behavior\Connect', ], 'app_end'=> [ 'app\index\behavior\End' ] ];
可以在控制器下目錄下使用 tags.php 進(jìn)行綁定。