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调用方法后

  • 相关阅读:
    kali环境下如何安装最新版cobalt strike
    win10结束进程时拒绝访问的处理办法
    Windows下Postgresql数据库的下载与配置方法
    ubuntu下安装及配置git的方法
    运行和控制Nginx
    nginx安装(详解)
    ubuntu安装nginx
    在Windows安装运行Kafka
    linux下安装使用虚拟环境
    《操作系统真象还原》线程
  • 原文地址:https://www.cnblogs.com/itfenqing/p/7056549.html
Copyright © 2011-2022 走看看