企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 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进来的两个导航项