标签:action comm 网上 命名空间 加载 就会 comment ted 构造
自从我了解了钩子以后就一直在想一个东西,就是调用一个全局变量,然后就自动调用一个方法,然后我就在网上各种找资料,没有找到哪怕是一个相关的;
后面我仔细解剖了下这个需求,其实就两点要点:
1:要调用的这个全局变量要各种处理好了的
2:在这个方法中只会调用一次,而不是每次调用都调用这个方法
想通这两点后我首先想到了的就是钩子,钩子会在加载方法前先调用,符合这两点,但是有个很大的限制,就是只能勾指定方法,当我要用多个方法的时候就显得很无力了,我总不能说每个方法我都写一个专有的钩子方法或专有的钩子吧,这太麻烦我就放弃了;
后面我就想到了注解,把要调用的方法写在注解中,然后通过反射区读取注解,读取到注解就简单了,就可以通过钩子去勾对应的方法了;
我用的是thinkphp5 所以我实例代码就用这个环境来写的
首先是要调用全局变量的方法
/**
* @Annotation (aid,id)
* 上面括号里面可以放多个,以“,”隔开
*/
public function get(){
$this->id;
$this->aid;
}
然后我的钩子是放在父类的id和aid可以在父类定义,用于全局
/**
* 钩子加反射实现aop
*/
protected function hook()
{
$request= Request::instance();
$controller = explode(‘.‘, $request->controller());
$action = $request->action();
$controller = !is_array($controller) ? $controller : $controller[count($controller)-1];
//判断类是否存在,防止要实例的类不在这个命名空间
if(class_exists($controller)) return;
//判断类中是否有指定方法,由于是放在父类所以我用的是$this,但是在不是父类的方法中就放 new $controller()
if(!method_exists($this, $action)) return;
//获取反射,由于是放在父类所以我用的是$this,但是在不是父类的方法中就放 new $controller()
$re = new \ReflectionClass($this);
//获取注解
$comment = $re->getMethod($action)->getDocComment();
preg_match_all(‘/@Annotation\s+\((.*)\)/‘, $comment, $data);
$annotation = $data[1][0];
//有值的时候就执行
if(strlen($annotation) != 0)
{
$annotation = explode(‘,‘, $annotation);
foreach ($annotation as $k => $v)
{
//判断类中是否有指定的方法,由于是放在父类所以我用的是$this,但是在不是父类的方法中就放 new $controller()
if(method_exists($this, $v))
{
$this->$v();
}
}
}
}
然后就在构造方法中调用
public function _initialize()
{
$this->hook();
}
写在最后
有一点要注意,检测到类中没有要勾的方法是不会执行对应的方法的;
肯定会有人想不到运用场景,这个的运用场景是非常广泛的,就比如说以往我们接收到id后都要先各种判断,然后才敢用这个id,如果这时候这些判断这些先封装成一个类,然后用我这个方法调用,不就可以直接用了呀
然后也会有人说都封装成一个类了直接用$this调用不就好了,我会告诉他简单几个是很简单,但是有很多呢,就会有一大串,看起来很不舒服然
标签:action comm 网上 命名空间 加载 就会 comment ted 构造
原文地址:https://www.cnblogs.com/zhangzhaowen/p/11763270.html