php中的控制反转和依赖注入,php的依赖注入和控制反转

本文介绍了PHP中的控制反转(IoC)和依赖注入(DI)概念,通过示例代码展示了如何实现。在传统的编程中,类A依赖于类B,需要在A中实例化B。而IoC则是将这种依赖关系转移到外部管理,通过IoC容器来创建和注入依赖。文中还提到了使用反射API进一步优化依赖关系的处理,但指出这种方式存在无法提前生成所有实例和未解决多层依赖的问题。
摘要由CSDN通过智能技术生成

一、初步探索

控制反转,反转是相对于正转来说的,下面是正转的代码

class A{

public function __construct(){

$this->b = new B();

}

public function aMethod(){

return $this->b->bMethod();

}

}

class B{

public function __construct(){}

public function bMethod(){

return 12;

}

}

$b = (new A)->aMethod();

A类中的代码需要依赖B类,然后我们就在A的代码中实例化B类,然后调用B类中的方法

缺点:如果有多个地方需要用到B的实例化对象的话,就需要复制多次该代码

控制反转的代码

class A{

protected $b;

public function __construct(B $b){

$this->b = $b;

}

public function getB(){

return $this->b->abc();

}

}

class B{

public function __construct(){}

public function abc(){

echo 23;

}

}

class Ioc{

protected $instance = [];

public function __construct(){

$this->instances['B'] = new B();

$this->instances['C'] = new C();

$this->instances['D'] = new D();

}

public function make(string $abstract){

return $this->instances[$abstract];

}

}

echo '

'

$ioc = new Ioc();

$b = $ioc->make('B');

$a = new A($b);

$a->getB();

控制反转在外部处理好依赖关系,不需要在A中直接new B,而是让IoC容器将B给我,这就叫控制反转IoC

书面解释:将组件间的依赖关系从程序内部提到外部来管理。控制反转是站在A的立场来看的,它是拿B的

控制反转是说创建对象的控制权进行转移,以前创建对象的主动权和创建时机是自己把控的,而现在这种权利转移到第三方,比如转移交给了IoC容器,它是一个专门用来创建对象的工厂(BeanFactory),你要什么对象他就给你什么对象,有了IoC容器,依赖关系就变了,原先的依赖关系就没了,他们都依赖IoC容器里,通过ioc容器来建立他们之间关系

书面解释:组件间的依赖通过外部以参数或其他形式注入就是依赖注入DI,依赖注入是站在IoC立场上来看的,它是送B的

依赖 注入:IoC/DI容器注入某个对象所需要的外部资源

控制 反转:IoC/DI容器控制对象、控制对象实例的创建,主动权的转移

缺点明显:

1、无法提前生成所有的实例化对象

2、没有解决多层依赖的问题,仅仅是将依赖关系从程序内部提到了外部管理

二、进一步探索

在PHP运行时,扩展分析程序,导出或提出关于类、方法、属性、参数等的详细信息,包括注释。这种动态获取信息以及动态调用方法的功能称为反射API

class A{

public function __construct(B $b){

$this->b = $b;

}

public function getB(){

$this->b->bMethod();

}

}

class B{

public function __construct(C $c, D $d){

$this->c = $c;

$this->d = $d;

}

public function bMethod(){

echo '我是B中的方法bMethod()';

}

}

class C{

public function __construct(){}

public function cMethod(){

echo '我是C中的方法cMethod()';

}

}

class D{

public function __construct(){}

public function dMethod(){

echo '我是B中的方法dMethod()';

}

}

class Ioc{

protected $instance = [];

public function __construct(){}

public function getInstance($abstract){

//获取类的反射信息,也就是类的所有信息

$reflector = new ReflectionClass($abstract);

//echo $reflector->getDocComment();//获取类的注释信息

//获取反射类的构造函数信息

$constructor = $reflector->getConstructor();

//获取反射类的构造函数的参数

$dependencies = $constructor->getParameters();

if(!$dependencies){

return new $abstract();

}

//一个类可能有多个依赖类

foreach ($dependencies as $dependency){

if(!is_null($dependency->getClass())){

$p[] = $this->make($dependency->getClass()->name);

//这里$p[0]是c的实例化对象,$p[1]是D的实例化对象

}

}

//创建一个类的新实例,给出的参数将传递到类的构造函数

//构造出B的实例化对象,向上反推到A的实例化对象

return $reflector->newInstanceArgs($p);

}

public function make($abstract){

return $this->getInstance($abstract);

}

}

$ioc = new Ioc();

$a = $ioc->make('A');

$a->getB();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值