PHP反射实现对类的方法依赖注入和构造函数依赖注入

前段时间一直在看tp5 发现他内部实现了控制器的依赖注入。。下面 我通过代码来说明一下是怎么实现的。

首先我们准备好几个类文件  我们先看目录安排


其中 start.php是启动文件

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/4/17
 * Time: 21:04
 */

header("Content-type: text/html; charset=utf-8");
require 'auto1.php';
require 'auto2.php';
require 'auto3.php';
require 'auto4.php';

class App{

    public static function run()
    {
        $class = 'auto1';
        $sh1 = 'sh1';
        $sh3 = 'sh3';

        self::exec($class,$sh1);

    }

    //执行反射类方法。
    public static function exec($class,$methodname)
    {
        //注入的实质是通过php的反射类 来执行被注入类的行为
        //通过反射 可以得到类的一些信息 主要包括方法 属性
        //通过注入 我们可以实现类对方法和构造方法的依赖。下面我举例说明
        //1.先肯定是从一个类的构造函数开始。
        //2.利用反射得到这个类的构造函数 在执行
        $reflect     = new \ReflectionClass($class);
        $constructor = $reflect->getConstructor();
        $p1 = self::getParamValue($constructor);
        //执行被反射类的构造函数 实现构造函数的依赖注入
        $instance = $reflect->newInstanceArgs($p1);
        //执行注入类的方法。
        $reflect = new \ReflectionMethod($class, $methodname);
        $p2 = self::getParamValue($reflect);
        //执行方法注入。
        $reflect->invokeArgs($instance, $p2);
    }
    //这个类用来 反射出当前注入类所在的参数。
    private static function getParamValue($reflect,$avgs=[])
    {
        if ($reflect->getNumberOfParameters() > 0)
        {
            foreach ($reflect->getParameters() as $param) {
                $param_type = $param->getClass();//获取当前注入对象的类型提示
                $param_value = $param->getName();//获取参数名称
                if($param_type)
                {
                    //表示是对象类型的参数
                    $avgs[] = new $param_value;
                }
                else
                {
                    $avgs[] = $param_value;
                }
            }
        }
        return $avgs;
    }
}
//执行应用程序
App::run();

auto1.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/4/17
 * Time: 21:30
 */

class auto1{

    public function __construct(auto4 $auto4)
    {
        $auto4->sh();
    }

    public function sh1(){
        echo '我是没有参数的方法sh1,我被执行了<br>';
    }

    public function sh3(auto2 $auto2,auto3 $auto3)
    {
        $auto2->sh();
        $auto3->sh();
    }
}

auto2.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/4/17
 * Time: 21:31
 */

class auto2{
    public function sh(){
        echo '我是auto2,我被执行到了,说明依赖注入成功了<br>';
    }
}

auto3.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/4/17
 * Time: 23:18
 */

class auto3{
    public function sh(){
        echo '我是auto3,我被执行到了,说明依赖注入成功了<br>';
    }
}

auto4.php

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/4/18
 * Time: 21:03
 */

class auto4{
    public function sh(){
        echo '我是auto4,我被执行到了,说明依赖注入成功了<br>';
    }
}

调用方式



执行效果





执行效果



这样就实现了。你可以想象一下 tp5的控制器是不是就是我们这里的auto1这个类啊。我剥离了它的依赖代码,核心就是我那个App类的2个方法了。

猜你喜欢

转载自blog.csdn.net/dzyweer/article/details/80011166