zoukankan      html  css  js  c++  java
  • 利用反射给类中方法加钩子

    有一个类如下所示:

    class Test
    {
        private $name = 'ok';
    
        public function __beforePrintname()
        {
            echo '调用方法前';
        }
    
        public function printName()
        {
            echo 'ok';
        }
    
        public function __afterPrintname()
        {
            echo '调用方法后';
        }
    }
    

      

    我们希望在实例化后调用printName方法前能调用__beforePrintname,调用printName后能调用__afterPrintname;给这个方法前后都加一个钩子方法

    我们可以使用反射来实现,代码如下:

    class Proxy
    {
        private $arrObject = [];
    
        public function __construct($obj)
        {
            $this->arrObject[] = new $obj();
        }
    
        public function __call($name, $arguments)
        {
            foreach ($this->arrObject as $obj) {
                $ref = new ReflectionClass($obj);
                if ($method = $ref->getMethod($name)) {
                    if ($method->isPublic()) {
    
                        // 调用方法前
                        $beforeMethodName = '__before' . $name;
                        if ($ref->hasMethod($beforeMethodName)) {
                            $beforeMethod = $ref->getMethod($beforeMethodName);
                            if ($beforeMethod->isPublic()) {
                                $beforeMethod->invoke($obj, $arguments);
                            }
                        }
    
                        // 调用方法
                        $method->invoke($obj, $arguments);
    
                        // 调用方法后
                        $afterMethodName = '__after' . $name;
                        if ($ref->hasMethod($afterMethodName)) {
                            $afterMethod = $ref->getMethod($afterMethodName);
                            if ($afterMethod->isPublic()) {
                                $afterMethod->invoke($obj, $arguments);
                            }
                        }
                    }
                }
            }
        }
    }
    

      

    测试:

    $test = new Proxy('Test');
    $test->printName();
    

      

    输出:

    调用方法前ok调用方法后

  • 相关阅读:
    VC++数据类型最佳解释
    C++类型转换
    内核态和用户态
    AZMan使用经验点滴
    解析#pragma指令(转)
    htc使用心得
    在VS.net 2008中利用ATL来创建COM关于接口文件的引用变动
    移植Reporting Service报表到项目报表
    const常量、指向常量的指针和常量指针(转)
    extern用法详解(转)
  • 原文地址:https://www.cnblogs.com/itfenqing/p/7056549.html
Copyright © 2011-2022 走看看