# Hook
Hook 本身是鉤子的意思,在程序中是一種簡化的Event的事件機制,這些“鉤子”會埋在特定代碼中,標示鉤子所在的位置。當代碼執行到該Hook時,觸發對應的 Hook Function 并按順序執行,如果沒有任何對應的 Hook Function ,則不不會改變任何事情。
Hook 目前有兩種,分別是”Action“及”Filter“,Action和Filter的使用方法是一樣的,但是用處略有不同,Action一般用于某些動作,Action永遠不會返回任何東西,而Filter用于處理數據,總是返回對某個數據處理后的數據
# Action Hook 動作處理
編寫中
# Filter Hook 數據處理
Filter 類型的Hook主要是用來處理數據,在程序運行中,你可以針對Hook的數據進行改變,這樣的好處是可以解除程序耦合,比如定義了一個數組,如果希望在別的地方能改變它,而不是直接修改這個數組,那么我們就可以使用Filter
Filter Hook 提供了兩個方法來處理數據,分別是:用于觸發鉤子的Filter::fire() 和 用于監聽鉤子的Filter::listen()
添加一個Filter鉤子,你只需要在用到在需要處理數據的地方觸發這個鉤子,如我們有一個數據‘Hello Filter’需要處理:
~~~
$hello = Filter::fire('hook.hello', 'Hello Filter');
~~~
如果沒有添加任何對這個filter的監聽處理,那么$hello值依然是 ‘Hello Filter’,但是如果我們添加了一個Filter監聽:
~~~
Filter::listen('hook.hello', function ($value) {
$value = '你好,Filter';
return $value;
});
~~~
此時$hello 的值將變成 ‘你好,Filter’
如果我們在別的地方有另外一個對‘hook.hello’的監聽
~~~
Filter::listen('hook.hello', function ($value) {
// 這時的$value已經不再是'Hello Filter',而是上一個監聽器返回的數據 ‘你好,Filter’
$value = $value . '=== :)';
return $value;
});
~~~
此時$hello 的值將變成 ‘你好,Filter=== :)’
fire的第一個參數是鉤子名稱,第二個參數是等待hook的數據,他將依次參入下一個監聽中進行處理,當然我們也可以擁有更多參數,但是第三、第四甚至更多的參數只能用來輔助處理第二個參數
listen的第一個參數同樣是鉤子名稱,第二個參數是閉包函數或者類的方法(MyNamespace\Listen@myListen),第三個參數是優先級,如果不定義優先級,那么優先級默認為20
~~~
$value = Filter::fire('hook.second', $param, $argument1);
// 此時 $value 為 $param
~~~
~~~
// 添加第一個閉包監聽
Filter::listen('hook.second', function ($param, $argument1) {
$param = $param + $argument1
return $param;
});
// 此時 $value 為 $param + $argument1
~~~
~~~
// 再添加一個類方法監聽
Filter::listen('hook.second', MyNamespace\Listen@myListen);
//MyNamespace\Listen中
public function myListen ($param, $argument1)
{
// 此時傳入的$param已經變成了上一次監聽返回的結果 ($param + $argument1)
$param = $param + $argument1*2
return $param;
}
// 此時 $value 為 ($param + $argument1) + $argument1*2
~~~
舉個實際例子:在系統后臺的頭部我們有個主導航條,我們希望你能在自己的模塊或者其它地方擴展它,所以我們定義了一個名稱為 **global.navbar** 的Filter觸發器,用來擴展導航(默認并沒有任何導航,所以傳入的待處理導航數據是空數組)
`Filter::fire('global.start',[])`
在Core模塊的start.php中,我們對該Filter進行監聽處理
~~~
\Filter::listen('global.navbar', function($navbar){
// 主頁
$navbar['core.index'] = [
'text' => trans('core::master.index'),
'href' => route('admin.index'),
'class' => 'index',
'active' => Route::is('admin.index')
];
return $navbar;
},1);
~~~
這時候我們就成功添加了一個導航,在Site模塊的start.php中,我們繼續對該Filter進行監聽處理
~~~
\Filter::listen('global.navbar',function($navbar){
// 站點名稱
$navbar['core.sitename'] = [
'text' => config('site.name'),
'href' => route('site.config.base'),
'class' => 'sitename',
'active' => Route::is('site.*')
];
return $navbar;
},0);
~~~
這時候我們又添加了一個導航到主導航中,在實際的導航展示中,代碼如下:
~~~
@foreach(Filter::fire('global.navbar',[]) as $navbar)
<li class="item {{$navbar['class'] or ''}} {{$navbar['active'] ? 'active' : ''}}">
<a href="{{$navbar['href']}}">{{$navbar['text']}}</a>
</li>
@endforeach
~~~
這時候我們實際上展示出來是hook進來的兩個導航項