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');
  • 相关阅读:
    windows查看端口命令
    lombok
    Linux之文档与目录结构 目录的相关操作 Linux的文件系统
    VMware与Centos系统安装 和重置root密码
    shell 基本命令
    centos 安装教程 服务器配置教程 服务器中安装python 服务器中安装Django 安装MySQL 配置MySQL
    {Django基础十之Form和ModelForm组件}一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 ModelForm
    {Django基础九之中间件} 一 前戏 二 中间件介绍 三 自定义中间件 四 中间件的执行流程 五 中间件版登陆认证
    {Django基础八之cookie和session}一 会话跟踪 二 cookie 三 django中操作cookie 四 session 五 django中操作session
    老师的blog整理 .网络编程部分 .网络编程部分 前端部分 django基础部分
  • 原文地址:https://www.cnblogs.com/zhouyuanpei/p/15797930.html
Copyright © 2011-2022 走看看