[李景山php]每天TP5-20170106|thinkph
<?php//+----------------------------------------------------------------------//|ThinkPHP[WECANDOITJUSTTHINK]//+----------------------------------------------------------------------//|Copyright(c)2006~2016http://thinkphp.cnAllrightsreserved.//+----------------------------------------------------------------------//|Licensed(http://www.apache.org/licenses/LICENSE-2.0)//+----------------------------------------------------------------------//|Author:liu21st<liu21st@gmail.com>//+----------------------------------------------------------------------namespacethink;usethink\App;//应用usethink\Debug;//调试usethink\Log;//日志//上述基本上就已经直接包含类了classHook{privatestatic$tags=[];//钩子仓库/***动态添加行为扩展到某个标签*@paramstring$tag标签名称*@parammixed$behavior行为名称*@parambool$first是否放到开头执行*@returnvoid*/publicstaticfunctionadd($tag,$behavior,$first=false)//动态添加行为扩展到某个标签{//add($tag,$behavior,$first)isset(self::$tags[$tag])||self::$tags[$tag]=[];//初始化仓库对应的标签,经典的写法//isset(self::$tags[$tag])||self::$tags[$tag]=[];if(is_array($behavior)&&!is_callable($behavior)){//如果是行为名称是数组,并且不能被调用if(!array_key_exists('_overlay',$behavior)||!$behavior['_overlay']){//如果不存在这个_overlay的key或者这个key的值为空unset($behavior['_overlay']);//再次清除一下这个数据self::$tags[$tag]=array_merge(self::$tags[$tag],$behavior);//合并当前标签及行为}else{unset($behavior['_overlay']);//清除重写标签self::$tags[$tag]=$behavior;//重写}}elseif($first){//如果需要放到开头执行单个行为array_unshift(self::$tags[$tag],$behavior);//压入开始位置}else{self::$tags[$tag][]=$behavior;//否则放到后面}}/***批量导入插件*@paramarray$tags插件信息*@paramboolean$recursive是否递归合并*/publicstaticfunctionimport(array$tags,$recursive=true){//批量导入,基本上的批量导入,都是tag标签都是foreach循环if($recursive){//递归合并foreach($tagsas$tag=>$behavior){self::add($tag,$behavior);}}else{self::$tags=$tags+self::$tags;//普通合并}}/***获取插件信息*@paramstring$tag插件位置留空获取全部*@returnarray*/publicstaticfunctionget($tag='')//经典的获取方案,数据{if(empty($tag)){//获取全部的插件信息returnself::$tags;}else{returnarray_key_exists($tag,self::$tags)?self::$tags[$tag]:[];}}/***监听标签的行为*@paramstring$tag标签名称*@parammixed$params传入参数*@parammixed$extra额外参数*@parambool$once只获取一个有效返回值*@returnmixed*/publicstaticfunctionlisten($tag,&$params=null,$extra=null,$once=false){$results=[];//仓库$tags=static::get($tag);//太多类内部外包了foreach($tagsas$key=>$name){//此处的name应该是行为的具体情况是class名称$results[$key]=self::exec($name,$tag,$params,$extra);if(false===$results[$key]){//如果返回false则中断行为执行break;}elseif(!is_null($results[$key])&&$once){//一次break;}}return$once?end($results):$results;//返回最后的结果}/***执行某个行为*@parammixed$class要执行的行为*@paramstring$tag方法名(标签名)*@paramMixed$params传人的参数*@parammixed$extra额外参数*@returnmixed*/publicstaticfunctionexec($class,$tag='',&$params=null,$extra=null){//执行对应的类App::$debug&&Debug::remark('behavior_start','time');//行为记录if(is_callable($class)){$result=call_user_func_array($class,[&$params,$extra]);$class='Closure';}elseif(is_object($class)){$result=call_user_func_array([$class,$tag],[&$params,$extra]);$class=get_class($class);}else{$obj=new$class();$result=($tag&&is_callable([$obj,$tag]))?$obj->$tag($params,$extra):$obj->run($params,$extra);}if(App::$debug){Debug::remark('behavior_end','time');Log::record('[BEHAVIOR]Run'.$class.'@'.$tag.'[RunTime:'.Debug::getRangeTime('behavior_start','behavior_end').'s]','info');}return$result;}}//其实hook就是一个以标签tag为抓手的一类函数的执行//就是这个意思,根本就没有所谓监听的意图
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。