php反射机制实现自动依赖注入

<?php

/**
 * 工具类 使用该类来实现自动依赖注入
 * @param
 */
class Ioc
{

    /**
     * 获得类的对象实例
     * @param string $className 类名称
     * @return object
     * @throws \ReflectionException
     */
    public static function getInstance($className = '')
    {
        $params = self::getMethodParams($className);

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

    /**
     * 执行类的方法
     * @param $className 类名称
     * @param $methodName 类方法名称
     * @param array $params 所传入的参数
     * @return mixed
     * @throws \ReflectionException
     */
    public static function make($className, $methodName, $params = [])
    {
        //获取类的实例
        $instance = self::getInstance($className);

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

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


    /**
     * @param $className 类名称
     * @param String $methodName  方法名称
     * @return array
     * @throws \ReflectionException
     */
    protected static function getMethodParams($className,$methodName = '__construct')
    {
        //通过反射类获得该类
        $reflection = new ReflectionClass($className);


        //记录参数
        $params = [];


        //判断该类是否有构造函数
        if($reflection->hasMethod($methodName))
        {
            //获取构造函数
            $construct = $reflection->getMethod($methodName);

            $constructParams = $construct->getParameters();

            if(count($constructParams) > 0)
            {
                foreach ($constructParams as $constructParam) {
                    if($paramClass = $constructParam->getClass())
                    {

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

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

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

           
        }

        return $params;
    }
}



//上面的代码使用php的反射函数,创建了一个容器类,
//使用该类来实现其他类的依赖注入功能。
//上面的依赖注入分为两种,
//一种是构造函数的依赖注入,
//一种是方法的依赖注入。
//我们使用下面三个类来做下测试。

/**
 * 
 */
class Human
{

	protected $menObj;
	/**
     * 用于测试多级依赖注入 Man依赖Human,Human依赖Men
     * @param Men $men 
     */
	function __construct(Men $men)
	{
		$this->menObj = $men;
	}

	public function getHuman()
	{
		echo 'this test $humen->getHuman()';
	}

	public function getMen()
	{
		$this->menObj->getMen();
	}
}

/**
 * @param 传入Humen , Man 依赖Human 反过来说Huname 控制Man
 */
class Man 
{
	protected $humanObj ;


    /**
    * 测试构造函数依赖注入
    * @param Human $human
    */
	public function __construct(Human $human)
	{
		$this->humanObj = $human;
	}


     /**
     * [测试方法调用依赖注入]
     * @param  Men      $men [依赖注入Men]
     * @param  string $params [这个是自己手动填写的参数]
     * @return [type]    [description]
     */
    public function getMan(Men $men, $param ) {
 
        $men->getMen();
        echo "\r\n";
 
        echo 'param:' . $param;
       
    }



    /**
    * 获取Human类的方法
    */
     public function getHuman()
     {
     	$this->humanObj->human();
     }


     /**
    * 获取Men类的方法
    */
     public function getMen()
     {
     	$this->humanObj->getMen();
     }
}





class Men 
{
	
	public function getMen() {
 
        echo 'this is Men->getMen';
    }
}



//测试构造函数的依赖注入

// 使用Ioc来创建Man类的实例,Man的构造函数依赖Human类,Human的构造函数依赖Men类。

$manObj = Ioc::getInstance('Man');

$manObj->getMen(); // 输出:this is Men->getMen , 说明依赖注入成功。
 
// 打印$bObj
var_dump($manObj);

输出:object(Man)[3]
  protected 'humanObj' => 
    object(Human)[7]
      protected 'menObj' => 
        object(Men)[10]




//测试方法依赖注入:
Ioc::make('Man', 'getMan', ['this is param man']);
 

输出:this is Men->getMen param:this is param man
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝颜~岁月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值