直接执行行为

如果需要,你也可以不绑定行为标签,直接调用某个行为,使用:

  1. // 执行 app\index\behavior\CheckAuth行为类的run方法 并引用传入params参数
  2. $result = Hook::exec('app\\index\\behavior\\CheckAuth',$params);

直接执行行为的时候,执行的是run方法,如果需要执行行为类的其它方法,可以使用

// 执行 app\index\behavior\CheckAuth行为类的hello方法 并引用传入params参数
$result = Hook::exec(['app\\index\\behavior\\CheckAuth','hello'], $params);

讲个小故事
有一天客户说要求实现一个会员的注册模块。
我这里键盘敲了半天完成了代码会员的注册模块。
第二天客户说“现在客户注册没问题了,我想能不能在注册完成后给他添加50积分,让他能进行一些消费。”,我说“没问题”
敲敲敲半天代码我完成了客户的要求。现在注册会员后,有赠送50积分了。
第三天同事问我你前两天不是在系统里弄了个注册模块和赠送积分?我说是啊。同事说“把你这个提交一下svn库,我这边也有个客户想弄个注册模块和赠送积分,还要添加发送邮件验证”,我:“好的,不过你要自己添加发送邮件验证。”代码提交到svn库,
同事敲了半天代码,完成了发送邮件。
第四天我找同事让他提交一下SVN库,让我进行一下代码同步。
第五天另一个客户问我“你们的注册模块有没有会员注册验证手机”,这个我当然只能说有(实际上是没有短信认证),客户说”能装好环境让我测试一下?“,我只能说:“抱歉先生,我们现在还没装好环境,这个我明天给您装好,您在测试一下”,客户说“好”
蹭蹭蹭敲了半天代码在会员注册模块上面加了会员注册手机验证。
第六天客户觉得挺好的。
故事讲到这里。
假设以上会员注册模块的形成是这样的一段代码片段:

namespace app\index\controller;

class member{
       function register($username , $password , $tel , $email){
              // 第五天加的代码:
              if(是否短信验证)
                     VerifTel($tel , 验证码);
              // 第一天写的代码:
              if(table('member')->where('username' , $username)->count())
              {
                     $this->error = '用户名已存在'
                     return false;
              }
              $uid = 写入数据库得到新的用户UID
              ....省略大部分代码

              // 第二天加的代码:
              if(赠送积分)
                    sendPoints($uid . 赠送积分); // 发送积分50
              // 第三天
             if(发送邮件)
                   sendEmail($uid , 邮件);

             return true;
       }
}

从以上我们可以看出,当写完一个功能模块的时候,并不知道客户一些需求的情况,我们会在当前模块中加入代码。
如果一直下去加下去,回头看代码的时候你会发现你的代码实在是太多了。
这个代码是不是可以变得优雅一些

如果我们在这个代码中加入钩子机制会是怎么样的呢?
看如下代码

namespace app\index\controller;
class member{
       function register($username , $password , $tel , $email){

              // 我不知道以后会变成什么样,先加个前置钩子,参数:$username,$password,$tel,$email
              $param = [ $username,$password,$tel,$email ];
              \app\common\Hook::call('member','registerPre',$param);

              // 第一天写的代码:
              if(table('member')->where('username' , $username)->count())
              {
                     $this->error = '用户名已存在'
                     return false;
              }
              $uid = 写入数据库得到新的用户UID
              ....省略大部分代码

             // 我不知道以后会变成什么样,先加个注册成功后的钩子,参数 $uid
              $param = [ $uid ];
              \app\common\Hook::call('member','registerSuccess',$param);

             return true;
       }
}

那么问题来了我们怎么去解决钩子的问题?
假设我们的类都已经注册进了钩子里:
我们来完成第二天的事情,如下代码:

namespace app\index\hook;
class member{
       // 钩子类型,挂入 member 类型钩子,中的registerSuccess钩子
       function registerSuccess($uid)
       {
              if(赠送积分)
                    sendPoints($uid . 赠送积分); // 发送积分50
       }
}

第三天的时候同事要用我的代码怎么办?那么我会告诉他:“我这边已经下了两个钩子,一个是注册前置钩子,一个是注册成功后的钩子”并告诉他钩子类型,名称,还有相应的参数,同事的代码将变成这样

namespace app\tongshi\hook;
class member{
       // 钩子类型,挂入 member 类型钩子,中的registerSuccess钩子
       function registerSuccess($uid)
       {
              if(发送邮件)
                   sendEmail($uid , 邮件);
       }
}

第五天的时候这样的:

namespace app\index\hook;
class member{
       // 挂入 member 类型钩子,中的registerSuccess钩子
       function registerSuccess($uid)
       {
              if(赠送积分)
                    sendPoints($uid . 赠送积分); // 发送积分50
       }
       // 挂入member 类型钩子中的registerPre钩子
       function registerPre()
       {
              if(是否短信验证)
                     VerifTel($tel , 验证码);
       }
}