php ioc - yaokun123/php-wiki GitHub Wiki

<?php
/**
 * Created by PhpStorm.
 * User: yaok
 * Date: 2021/4/12
 * Time: 下午4:49
 */


/**工具类,通过该类来实现自动依赖注入
 * Class Ioc
 */
class Ioc{


    //获得类的对象实例
    public static function getInstance($className){
        $paramArr = self::getMethodParams($className);

        return (new ReflectionClass($className))->newInstanceArgs($paramArr);
    }

    //执行类的方法
    public static function make($className,$methodName,$params=[]){
        //获取类的实例
        $instance = self::getInstance($className);

        //获取该方法所需要的依赖注入参数
        $paramArr = self::getMethodParams($className,$methodName);

        return $instance->$methodName(...array_merge($paramArr,$params));
    }

    protected static function getMethodParams($className,$methodsName='__construct'){
        //通过反射获得该类
        $class = new ReflectionClass($className);
        $paramArr = [];//记录参数,和参数类型

        //判断该类是否有构造函数
        if($class->hasMethod($methodsName)){

            //获取构造函数
            $construct = $class->getMethod($methodsName);

            //判断构造函数是否有参数
            $params = $construct->getParameters();
            if(count($params) > 0){

                //判断参数类型
                foreach($params as $key=>$param){
                    if($paramClass = $param->getClass()){

                        //获得参数类型名称
                        $paramClassName = $paramClass->getName();


                        //获得参数类型
                        $args = self::getMethodParams($paramClassName);

                        $paramArr[] = (new ReflectionClass($paramClassName))->newInstanceArgs($args);
                    }
                }
            }
        }

        return $paramArr;

    }

}



//测试
class A{
    protected $cObj;

    //用户测试多级依赖注入 B依赖A, A依赖C
    public function __construct(C $c)
    {
        $this->cObj = $c;
    }
    public function aa(){
        echo 'this is A->test';
    }
    public function aac(){
        $this->cObj->cc();
    }
}


class B{
    protected $aObj;

    //测试构造函数依赖注入 B依赖A
    public function __construct(A $a)
    {
        $this->aObj = $a;
    }

    //测试方法调用依赖注入
    public function bb(C $c,$b){
        $c->cc();
        echo PHP_EOL;
        echo 'params:'.$b;
    }


    //验证依赖注入是否成功
    public function bbb(){
        $this->aObj->aac();
    }
}


class C{
    public function cc(){
        echo 'this is C->cc';
    }
}

//测试构造函数的依赖注入
//使用Ioc来创建B类的实例,B的构造函数依赖A类,A的构造函数依赖C类
$bObj = Ioc::getInstance('B');
$bObj->bbb();//输出 this is C->cc,说明依赖注入成功
//var_dump($bObj);



//测试方法依赖注入
Ioc::make('B', 'bb', ['this is param b']);
// 输出结果,可以看出依赖注入成功。
//this is C->cc
//params:this is param b





/*class A{
    public $q = 1111;

}


class Test{
    public $a = 1;
    protected $b = 2;
    private $c = 3;
    public function __construct(A $a){
        echo "111";
    }
}

$a = Ioc::getInstance('Test');
print_r($a);*/