thinkphp的CBD模式 核心保留了最關鍵的部分,併在重要位置設置了標簽用以標記,其他功能都採用行為擴展和驅動的方式組合,開發人員可以根據自己的需要,對某個標簽位置進行行為擴展或者替換,就可以方便的定製框架底層,也可以在應用層添加自己的標簽位置和添加應用行為。而標簽位置類似於AOP概念中的“切麵 ...
thinkphp的CBD模式
核心保留了最關鍵的部分,併在重要位置設置了標簽用以標記,其他功能都採用行為擴展和驅動的方式組合,開發人員可以根據自己的需要,對某個標簽位置進行行為擴展或者替換,就可以方便的定製框架底層,也可以在應用層添加自己的標簽位置和添加應用行為。而標簽位置類似於AOP概念中的“切麵”,行為都是圍繞這個“切麵”來進行編程。
CBD主要由Core(核心)、Behavior(行為)以及Drivers(驅動)三部分組成。在ThinkPHP中,Core是指諸如路由配置,基礎模型類、Behavior中使用到的行為標簽配置這些最重要的核心函數庫、類庫以及配置文件。Behavior是框架中比較關鍵的一種機制,在thinkphp中是實現了“鉤子”的功能,恰當的使用可以有效降低業務邏輯之間的耦合度,下麵會詳細。而Drivers是基於功能的,為框架的功能拓展提供驅動,比如資料庫驅動,緩存驅動。
Behavior(行為)
AOP
這種在運行時,動態地將代碼切入到類的指定方法、指定位置上的編程思想就是面向切麵的編程 http://hejiajunsh.iteye.com/blog/1776569
AOP(Aspect Oriented Program)與傳統的面向對象編程並不衝突,反而可以對OOP編程作出補充,增加某些代碼的重用性,降低不同業務邏輯之間的耦合度,使團隊開發更為容易且可以有效降低開發周期。
鉤子函數
鉤子是編程里一個常見概念,非常的重要。它使得系統變得非常容易拓展,(而不用理解其內部的實現機理,這樣可以減少很多工作量)。
可以理解為當一個玻璃球從空中落下,即將砸到人的時候,有個事件會提前發生.例如告訴那個被砸的人,球已經在下落過程中,
告訴就是一個事件,一個鉤子,我們可以針對不同的人做出不同的相應,如果是男人我們告訴他這個球砸到人不疼,如果是女人則告訴她很疼;
鉤子函數可以截獲並處理其他應用程式的消息。每當特定的消息發出,在沒有到達目的視窗前,鉤子程式就先捕獲該消息,亦即鉤子函數先得到控制權。這時鉤子函數即可以加工處理(改變)該消息,也可以不作處理而繼續傳遞該消息,還可以強制結束消息的傳遞。
設置鉤子的過程其實就是設置事件驅動的過程,簡單來講就是定義鉤子函數,註冊事件,監聽(掛載),滿足觸發條件並觸發鉤子函數。
行為拓展
行為(Behavior)是ThinkPHP擴展機制中比較關鍵的一項擴展,行為既可以獨立調用,也可以綁定到某個標簽(位)中進行偵聽。這裡的行為指的是一個比較抽象的概念,你可以想象成在應用執行過程中的一個動作或者處理,在框架的執行流程中,各個位置都可以有行為產生,例如路由檢測是一個行為,靜態緩存是一個行為,用戶許可權檢測也是行為,大到業務邏輯,小到瀏覽器檢測、多語言檢測等等都可以當做是一個行為,甚至說你希望給你的網站用戶的第一次訪問彈出Hello,world!這些都可以看成是一種行為,行為的存在讓你無需改動框架和應用,而在外圍通過擴展或者配置來改變或者增加一些功能。
換言之,TP框架中Behavior實現了AOP(面向切麵)編程,即綁定標簽,利用Hook函數設置觸發點。
tp提供了諸如'app_init'(應用初始化標簽位),'path_info'(path_info檢測標簽位),'app_began'(應用開始標簽位),'app_end'(應用結束標簽位)等內置標簽位。
行為拓展添加過程
- 創建Behavior類
可以直接放在Think\Behaviors中,也可以放在應用目錄中(Application\Common\Behavior),新建文件,命名格式為 標簽名+Behavior.class.PHP 。要註意類中必須含有run方法,預設run方法為入口方法。
代碼內容
namespace Common\Behavior;
use Think\Behavior;
class TolldetectBehavior extends Behavior
{
//方法名必須為run,作為入口文件
public function run(&$param){
echo "Hello ";
}
}
- 註冊標簽(掛載)
ThinkPHP中的標簽註冊方法有兩種,一種是手動註冊,一種是自動註冊。
下麵為手動註冊方法add()的源碼
/**
* 動態添加插件到某個標簽
* @param string $tag 標簽名稱
* @param mixed $name 插件名稱
* @return void
*/
static public function add($tag,$name) {
if(!isset(self::$tags[$tag])){
self::$tags[$tag] = array();
}
if(is_array($name)){
self::$tags[$tag] = array_merge(self::$tags[$tag],$name);
}else{
self::$tags[$tag][] = $name;
}
}
我們在調用時用Hook::add($tags,$name)就可以綁定。註意tags為要綁定的標簽名,$name為具體的behavior行為文件。
如果使用自動註冊,則需要在Common目錄下新建tags.php文件。其中可以直接通過返回數組的方法進行批量綁定,TP在運行中會自動載入這個配置併進行綁定。例如:
<?php
return array(
"hellow" => array('Home\\Behaviors\\TolldetectBehavior')
);
?>
以上代碼就完成了'hellow'標簽與我上面定義的事件的自動註冊。
當我們手動或自動完成了行為拓展的綁定,就可以設置事件的觸發點了。
觸發鉤子則會執行run方法。