<?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
php反射机制实现自动依赖注入
最新推荐文章于 2023-03-16 09:32:35 发布