zoukankan      html  css  js  c++  java
  • 依赖注入的PHP实现(二)

      上次实现了简单的依赖注入,但是有个问题,像laravel是可以实现构造函数依赖注入,但是上次实现的依赖注入不支持构造函数的依赖注入,所以今天把构造函数的依赖注入一并实现了。

      跟上次一样,假设有一个名为user的model

      

    class User
    {
        public $table = 'users';
    }

     我们还有个名为UserController的控制器,我们需要在UserController的构造方法中依赖注入User,如下图所示

      

    class UserController
    {
        protected $user;
    
         public function __construct(User $user){
            $this->user = $user;
         }
    
        public function getTableName(){
            echo $this->user->table;
        }
    }

      之前我们是直接new了个Usercontroller的实例给invokeArgs

    //携带参数执行该方法
    $reflectionMethod->invokeArgs(new $controller,self::getMethodParams($reflectionMethod));

      那么要实现构造函数的依赖注入,那么我们就需要在实例化UserController时把构造函数的依赖实例化并注入,查询了下php手册,发现了ReflectionClass类下有newInstanceArgs这个方法可以在实化类的时候传入参数,那我们故技重施,先通过反射类获取构造函数的信息,然后实例化参数,再调用newInstanceArgs实例化Usercontroller,这样就完成了构造函数依赖的注入。

        public static function run ($controller, $method)
        {
            if (! method_exists($controller, $method))
            {
                echo "Method [$method] is not exist !";exit;
            }
            
            //通过反射获取类信息
            $reflector = New ReflectionClass($controller);
    
            //获取构造方法信息,实例化参数
            $constructor = $reflector->getConstructor();
            $constructParams = self::getMethodParams($constructor);
    
            //创建一个类的新实例,给出的参数将传递到类的构造函数
            $instance = $reflector->newInstanceArgs($constructParams);
    
            //获取执行方法信息,实例化参数
            $reflectionMethod = New ReflectionMethod($controller,$method);
            $methodParams = self::getMethodParams($reflectionMethod);
    
            //执行反射的方法
            $reflectionMethod->invokeArgs($instance, $methodParams);
        }

       测试代码效果,成功输出了user的table属性

        

        所有示例代码如下

    <?php
    
    class User
    {
        public $table = 'users';
    }
    
    class Article
    {
        public $table = 'articles';
    }
    
    class UserController
    {
        protected $user;
    
         public function __construct(User $user){
            $this->user = $user;
         }
    
        public function getTableName(Article $article){
            echo $this->user->table . PHP_EOL; 
            echo $article->table;
        }
    }
    
    class app
    {
    
        public static function run ($controller, $method)
        {
            if (! method_exists($controller, $method))
            {
                echo "Method [$method] is not exist !";exit;
            }
            
            //通过反射获取类信息
            $reflector = New ReflectionClass($controller);
    
            //获取构造方法信息,实例化参数
            $constructor = $reflector->getConstructor();
            $constructParams = self::getMethodParams($constructor);
    
            //创建一个类的新实例,给出的参数将传递到类的构造函数
            $instance = $reflector->newInstanceArgs($constructParams);
    
            //获取执行方法信息,实例化参数
            $reflectionMethod = New ReflectionMethod($controller,$method);
            $methodParams = self::getMethodParams($reflectionMethod);
    
            //执行反射的方法
            $reflectionMethod->invokeArgs($instance, $methodParams);
        }
    
        /**
         * 获取方法的参数并实例化
         * @param $reflectionMethod
         *
         * @return array
         * @throws \Exception
         */
        public static function getMethodParams($reflectionMethod) : array
        {
            $result = [];
    
            foreach ($reflectionMethod->getParameters() as $key => $param) {
                $class = $param->getClass();
    
                if ($class)
                {
                    $result[] = New $class->name(); 
                }else{
                    throw New Exception('arguments ' . $key . 'is error!');
                }
            }
    
            return $result;
        }
    }
    
    app::run('UserController', 'getTableName');
  • 相关阅读:
    性能测试基本功 手动配置nginx+phpcgi+zend+mysql
    MySQL的show full processlist命令
    LoadRunner测试Webservices的例子
    Firefox 5 公开测试下载
    Shunra 即将发布 PerformanceSuite 7.0 和NetworkCatcher 7.0
    LoadRunner常见问题
    动态生成的图片保存成png格式
    如何解决ASP.NET程序安装到繁体系统上的乱码问题
    在Ubuntu上下载、编译和安装Android最新源代码
    腾讯微博api的蛋疼问题
  • 原文地址:https://www.cnblogs.com/zhouyuanpei/p/15797930.html
Copyright © 2011-2022 走看看