要理解php依赖注入和控制反转两个概念,必须弄清以下问题。
di ——从属注入
IOC ——控制控件反转
1、参加者有谁?
答:一般有三方参与者。 一个是某个对象。一个是IoC/DI的容器; 另一个是一个对象的外部资源。 为了说明名词,一个对象指向任何普通的Java对象; IoC/DI的容器,简单地说,就是实现IoC/DI功能的框架程序。 对象外部资源是指对象所需的资源,但从对象的外部取得的资源,是对象所需的其他对象、对象所需的文件资源等资源的总称。
2、依赖:谁依赖谁? 为什么会有依存?
a )某些对象依赖于IoC/DI的容器。 依赖是不可避免的。 在一个项目中,各级之间有各种各样的关系,并不是一切都完全独立。 这就形成了依存。 传统开发通过在使用其他类时直接调用来形成强绑定。 这需要避免。 注入借用容器转移被依存对象实现了去耦。
3、注入:谁给谁注入? 到底要注入什么?
答:通过容器向对象注入所需的外部资源
4、控制逆转:谁控制谁? 你控制什么? 为什么叫翻转?
a ) IoC/DI的容器控制对象主要是控制对象实例的创建。 翻转是相对兴奋的保温杯的方向,那么什么是正的呢? 考虑一下正常的APP应用。 如果在a中使用c的话,怎么办? 当然,直接创建c的对象,也就是说,积极获取a类中所需的外部资源c被称为正向。 那么,反方向是什么呢? a类不是主动获取c,而是被动等待,等待IoC/DI的容器获取c的实例,然后反向注入a类。
5、依赖注入和控制翻转是同一概念吗?
答:从上面可以看出,依赖注入是从APP应用的角度描述的,完全可以描述依赖注入。 APP应用依赖于创建和注入容器所需的外部资源; 控件的反转是从容器的角度描述的,描述了完整的点。 容器控制APP应用程序从容器反向注入APP应用程序所需的外部资源。
举个例子具体看看依赖注入的几种实现方法
1 .构建器注入
class Book {
隐私$ db _ conn;
公共函数_ _ construct ($ db _ conn ) {
$this-db_conn=$db_conn;
}
}
2、中心注入
复制代码
复制代码
class book{
隐私$数据库;
私有$文件;
functionsetdb($db ) {
$this-db=$db;
}
功能设置($ file ) {
$this-file=$file;
}
}
class file{}
class db{}
.
类测试{
$book=new Book (;
$book-setdb(newdb ) );
$ book-setfile (新文件) );
}
?
复制代码
复制代码
以上两种方法的代码很清楚,但如果需要注入很多依赖关系,就需要增加很多行,意味着管理变得困难。
好的解决方案是将类构建为所有依赖关系的容器。 此class允许您存储、创建、检索和搜索所需的依赖关系
复制代码
复制代码
类IOC {
保护性$ db _ conn;
公共静态功能标记_ book (
$new_book=new Book ();
$ new _ book-set _ db (self :3360 $ db _ conn );
//.
//.
//其他依赖注入
返回$ new _ book;
}
}
复制代码
此时,如果获得了book实例,则$newone=Ioc:makebook ();
以上是container的具体示例,但最好不要将具体的依赖注入写在方法中,而在registry中注册,在get中获取
类IOC {
//*
* @var注册的依赖数组
*/
保护性静态$ registry=array (;
//*
将resolve添加到注册表数组
* @param string $name依赖标记
p>* @param object $resolve 一个匿名函数用来创建实例
* @return void
*/
public static function register($name, Closure $resolve)
{
static::$registry[$name] = $resolve;
}
/**
* 返回一个实例
* @param string $name 依赖的标识
* @return mixed
*/
public static function resolve($name)
{
if ( static::registered($name) )
{
$name = static::$registry[$name];
return $name();
}
throw new Exception('Nothing registered with that name, fool.');
}
/**
* 查询某个依赖实例是否存在
* @param string $name id
* @return bool
*/
public static function registered($name)
{
return array_key_exists($name, static::$registry);
}
}
复制代码
复制代码
现在就可以通过如下方式来注册和注入一个
复制代码
复制代码
$book = Ioc::registry('book', function(){
$book = new Book;
$book->setdb('...');
$book->setprice('...');
return $book;
});
//注入依赖
$book = Ioc::resolve('book');
?>
复制代码
复制代码
以上就是针对php依赖注入和控制反转的理解,希望对大家学习PHP程序设计有所帮助
php依赖注入和控制反转
依赖注入是一种设计模式,又名 控制反转 ,为了降低耦合度
1:控制反转(Inversion of Control )的实现方式
简称:IOC
理解:A类不需要主动去获取C,而是被动等待,等待IoC/DI的容器获取一个C的实例,然后反向的注入到A类中。比如说,A类中需要用到C类,也可能是B类,而这时候,不需要再A类内部代码中去实例化C类或者B类,这样代码耦合性太高,不容易维护,为了降低耦合度,从而设计成A类中传递一个参数,而这个参数就是B类或者C类。
/ 定义写日志的接口规范
interface logApi {
public function write();
}
// 文件记录日志
class FileLog implements logApi {
public function write() {
echo 'file log write...';
}
}
// 数据库记录日志
class DatabaseLog implements logApi {
public function write() {
echo 'database log write...';
}
}
// 程序操作类
class User {
protected $fileLog;
public function __construct() {
$this->fileLog = new FileLog();
}
public function login() {
// 登录成功,记录登录日志
echo 'login success...';
$this->fileLog->write();
}
}
$user = new User();
$result = $user -> login();
代码这样写,耦合度高,如果将user类改成一下形式:
// 程序操作类
class User {
protected $fileLog;
public function __construct(Log $log) {
$this->fileLog = $log;
}
public function login() {
// 登录成功,记录登录日志
echo 'login success...';
$this->fileLog->write();
}
}
$user = new User(new FileLog());
$result = $user -> login();
这样想用任何方式记录操作日志都不需要去修改过User类了,只需要通过构造函数参数传递就可以实现,其实这就是“控制反转”。不需要自己内容修改,改成由外部外部传递。这种由外部负责其依赖需求的行为,我们可以称其为 “控制反转(IoC)
2:依赖注入
特点:
创建一个容易类,将用到的其他的类进行绑定到这个容器中,然后随时可以取用。
class luntai {
public function luntai1(){
echo "这是luntai.
";
}
}
class bmn {
private $luntaiClass;
public function __construct($luntai){
$this->luntaiClass = $luntai;
}
public function bmn(){
$this->luntaiClass->luntai1();
echo "这是bmn.
";
}
}
class Container {
static $register;
public static function bind($name,Closure $clo){
self::$register[$name] = $clo;
}
public static function make($name){
$clo = self::$register[$name];
return $clo();
}
}
Container::bind('luntai',function(){
return new luntai();
});
Container::bind('bmn',function(){
return new bmn(Container::make('luntai'));
});
$bmn = Container::make('bmn');
$bmn->bmn();
最后建议大家深入理解面向对象和多敲代码去理解它。