?在thinkPHP中的行為擴展和插件機制。
首先行為擴展這個概念是TP框架的核心組成之一,關于行為的解釋我就粗略的概括一下吧:
TP在從接受到HTTP請求到最終將試圖輸出,期間經歷的很多步驟,這些步驟大家可以在http://document.thinkphp.cn/manual_3_2.html#system_process這里面看到。
那么行為擴展實際上就是在這些流程里面買下了一個鉤子,你可以往鉤子里添加你自己的業務邏輯
當程序執行到某些鉤子位置時將自動觸發你的業務邏輯,http://document.thinkphp.cn/manual_3_2.html#behavior_extend。
本文的主要目的是教大家如何使用行為擴展和插件,這里為什么要提到“插件”這個詞呢?
因為在3.2里,有了一個插件的概念,和行為公用的HOOK類,所以放在一起說,原理上并無
并無太大區別。
-、行為擴展?
1.TP 內置行為鉤子
我們知道TP中預留一些行為鉤子,比如action_begin,這個鉤子實在動作開始執行時觸發,
預置的鉤子大家購過配置文件注冊行為類,大家在Application/Common/Conf目錄下創建一個
tags.php。這個和3.1是一樣的,返回一個數組。
數組個會是“鉤子名”=>“array(“行為類”,“行為類2”......................)”
這里我給一個例子:
Application/Common/Conf/tag.php:
<?php
return array(
"action_begin"=>array("Behaviors\\test")
);
?>
可以看到,我往action_begin這個鉤子里面注冊一個行為,這個行為就是Beha\\test這里
的寫法是命名空間寫法,其對應的類文件路徑是:
Application/Behaviors/testBehavior.class.php:
<?php
namespace Behaviors;
class testBehavior{
function run ($arg){
? echo "這里是一行為擴展"。$arg;
}
}
?>
千萬要注意第一行的命名空間,對于命名空間不理解的請自行查閱php手冊。
另外對于TP的自動加載機制,參考手冊:
http://document.thinkphp.cn/manual_3_2.html#autoload
行為的執行入口是run()方法,觸發鉤子時會自動執行行為類里的run()方法。
2.動態添加鉤子和注冊行為
通過上面的而梨子大家才是了解了行為大概是個什么東西,但是對于其執行流程
可能還不清楚,這里我來介紹下動態添加鉤子和注冊行為,是大家對行為執行機制
有一個比較清晰的理解。
首先,行為鉤子添加和注冊行為類,以及處罰行為,都是通過Hook類來實現的。
Hook類在TP核心包里的ThinkPHP目錄下,Hook.class.php。
>>添加鉤子以及注冊行為:\Think\HooK::(‘鉤子名’,‘行為’)
>>埋設/監聽/觸發鉤子:\Think\Hook::listen(‘鉤子名’,‘傳遞給run的參數,必須是個變量’ );
假如我們需要在訪問index.php/Public/login.html的時候觸發login鉤子里的行為,
那么首先我們需要在login方法中監聽鉤子,也就是把鉤子埋在login方法里,當訪問login方法就是
自動觸發,有點像獵人的陷阱。
function login(){
\Think\Hook::listen('login');
}
好了,我們在login方法里監聽了login鉤子,那么接下來我們往這個鉤子里添加一些行為,
這樣訪問login的時候會自動觸發這些行為,執行行為類的run方法。
行為在哪里注冊了?
1.你可以通過tags.php注冊,上面提到過了,只不過把action_begin換成login.
2.動態添加,假如這個鉤子只在Public控制器中使用,那么你可以子啊PUblicController的
_initialize()初始化方法腫么的動態添加鉤子。
function _initialeze(){
\Think\Hook::add('login','Behaviors\\test');
}
這里就往login這個鉤子里添加一個test行為,比較懶直接從上面復制下來。
可以同時添加多個行為類
\Think\Hook::add('login',array('Behaviors\\test','Behaviors\\test1'....));
就是第二個參數變成一個數組,數組里面每個元素對于一個行為類。
?
3.帶參數的行為
上面我們知道了行為是通過run()方法執行的,那么我們想傳遞一些參數進去怎么辦呢?
答案是\Think\Hook::listen();的第二個參數。
注意listen方法定義如下:
static public function listen($tag,&$param-NULL)
可以看到第二個參數是一個引用傳遞的參數,也就是說第二個參數必須是一個變量,不能是值,
下面的使用方法是錯誤的:
\Think\Hook::listen('login',"hello"); // x
這樣才是正確的
$hello = "hello";
\Think\Hook::listen('login',$hello);//√
這樣我們在行為類里面run方法可以指定一個參數來接收$hello
function run($arg){
echo $arg;//輸出 hello
}
當然你也可以
function run(&$arg){
echo $arg;//輸出hello
$arg = "bye";
}
這樣參數設定為引用類型,你可以在run里面改變原始變量的值。
二、插件
看了上面的行為,我們可以總結出一個模式:
定義不同的行為,執行同一個方法run ,而插件呢?
他是可以定義在run的并且相當于在一個行為類里面可以有多個入口,這些入口在不同的條件下觸發。
假設我們在tags.php里面添加了這樣一個鉤子
'showflash’=>array('test');
注意與行為的區別,注冊行為需要包含命名空間也是反斜杠\\,當沒有反斜杠,只有一個單詞的時候將認為是一個插件。
插件定義在Application/Addons/插件名/插件名Addon.class.php
插件類的定義
<?php
namespace Addons\test;
class testAddon{
function showflash(){
echo "這是插件執行入口";
}
}
?>
可以看出來一個明顯的區別,就是run入口變成了showfalsh,和鉤子名相同。
假如我們再來一個鉤子:
''=>
?