在看laravel源码的时候,在Container.php中有个build的方法,主要就是用了反射来进行实例化
参照它的写法,自己写了一个小例子
这里写的比较简单,就是一个依赖参数,正常应该普通参数也要放进去
类似在person类里的weight,address
public function __construct(Bag bag,weight, $address){}

 

<?php
/*
 * 目的:通过反射,自动找依赖注入的类。
 * 在实例的时候,里面的$bag, $book自动去查找,并且实例化
 * */

class Book{
    public function name(){
        return '语文书';
    }
}

class Bag{
    public $book;
    public function __construct(Book $book){
        $this->book = $book;
    }
 
    public function name(){
        return  "学生书包里有什么书呢 - ". $this->book->name()."\n";
    }

}
    
class Person{
    public $oneBag;
    public function __construct(Bag $bag){
        $this->oneBag = $bag;
    }

    public function goToSchool(){
        echo $this->oneBag->name();
    }

}

class Ioc{
    public static function getInstance($className){
        $obj = new ReflectionClass($className);
        $args = self::getParams($className);

//        $args = [new Bag(new Book)];//一开始调试,直接这个赋值,这是对的

        return $obj->newInstanceArgs($args);
    }

    public static function getParams($className){
        $paramArr = [];
        $reflector = new ReflectionClass($className);
        $construct = $reflector->getConstructor();
        if($construct){//判断是否有 __construct 方法
            $needParams = $construct->getParameters();
            foreach($needParams as $needParam){
                //如果传入的参数是个依赖注入的参数的话,而不是一个普通的参数。
                //像这里Bag实例化的时候又需要Book
                if($needParam->getClass()){
                    //如果__construct里的又是依赖注入,继续
                    $sonParam = self::getParams($needParam->getName());
                    $paramArr[] = (new ReflectionClass($needParam->getName()))
                                  ->newInstanceArgs($sonParam);
                }
            }
        }
        return $paramArr;
    }
}

$student = Ioc::getInstance('Person');
$student->goToSchool();
//打印 学生书包里有什么书呢 - 语文书

作者:maseraticc
链接:https://www.jianshu.com/p/9176b12eb843
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

最后更新于 2022年6月26日

模仿laravel,使用反射来实现自动依赖注入
标签: