php依赖注入与容器,Container,控制反转
依赖注入与Ioc容器
概念:
- 容器:可以理解为用来存放某个东西的物品(篮子?),存放的东西取决于你想往里面放点什么。在这里,我们是存放某个类,类的描述或者一个返回类实例的闭包函数。
- Ioc(Inversion of Control) 控制反转:可以理解为,你(用户),小红(容器)。你现在需要一把锤子,但你不想自己去造一个锤子去。你可以交给小红去处理。比如对小红说我想要一把锤子。小红会通过你给的工具名(锤子),通过自己的方法。去得到锤子的原材料(类的构造),接着在小红这里,直接造出来了一把锤子,不需要你来动手。你不需要知道这个锤子(类)所需的原材料(这里是指类的构造参数)。你通过小红(容器)而获取到了这个工具(类的实例).
- DI(Dependency Injection) 依赖注入:这和Ioc是同一种东西,但不同的是角度。例如:工具(锤子)依赖于小红(容器)去获取工具的原材料,并创建出工具(锤子).
特性:
- 减少系统之间的耦合性
- 增加代码稳定和健壮性
- 也可以理解为工厂模式的一种升级
php大神聚集地:294088839
Demo:
Class Demo1
{
public $name;
public function __construct(Demo2 $demo)
{
$this->demo = $demo;
}
public function Name()
{
$this->name = $this->demo->getName();
return $this->name;
}
}
//Demo2.php
Class Demo2
{
public function getName()
{
return "名字是xxx<br>";
}
}
//正常情况下,我们是需要先实例demo1然后在demo1的构造函数内传入demo2的
//实例,这样的耦合度太高,不宜于第二次扩展
//一般情况下的手法
//直接在new Demo1时就把Demo2给new出来并传入进去
$demo = new Demo1(new Demo2());
echo $demo->Name(); //输出名字是xxx //通过Ioc容器实现
Class Container
{
//存储当前类的实例
private static $instance;
//设置类不能直接new
private function __construct(){}
//禁止复制当前类
private function __clone(){}
//获取当前类的实例
public static function _ins()
{
//判断成员变量是否存储实例
if(empty(self::$instance))
{
//如果没有则存储并返回实例
self::$instance = new static();
return self::$instance;
}
//如果存储则直接返回
return self::$instance;
}
//成员变量register存储类的实例或类的描述
private $register = [];
//通过魔术方法__set和__get实现
//设置未定义的成员变量时,会经过__set
public function __set($key,$Cvalue)
{
//判断是否已经存储
if(array_key_exists($key,$this->register))
{
throw new Exception("错误,已存在这一的一个类");
}
$this->register[$key] = $Cvalue;
}
//访问未定义的成员变量
public function __get($key)
{
//通过build动态的去获取到类的实例
return $this->build($this->register[$key]);
}
//自动绑定,自动解析
public function build($ClassName)
{
//如果是匿名函数则直接返回执行后的结果
if ($ClassName instanceof Closure)
{
return $ClassName($this);
}
//通过反射获取到类的内部结构
$reflector = new ReflectionClass($ClassName);
//判断类能不能实例化,排除掉抽象类和接口
if(!$reflector->isInstantiable())
{
throw new Exception("对象不能实例化");
}
//获取到类的构造函数参数
$constructor = $reflector->getConstructor();
//判断构造参数是否没有定义,如果没有,则直接返回类实例
if(empty($constructor))
{
return new $ClassName();
}
//获取到构造函数内的参数
$params = $constructor->getParameters();
//递归的去调用方法解析并构造参数
$dependencies = $this->getDependencies($params);
//创建类的实例
return $reflector->newInstanceArgs($dependencies);
}
//解析参数
public function getDependencies($parameters)
{
//存储解析后的参数
$dependencies = [];
/** foreach循环获取参数,如果是变量并有默认值就直接返回默认值,如果没有 */
foreach ($parameters as $parameter) {
/** 通过反射获取到参数的类名,如果没有。。则直接返回默认值*/
$dependency = $parameter->getClass();
if (is_null($dependency)) {
// 是变量,有默认值则设置默认值
$dependencies[] = $this->resolveNonClass($parameter);
} else {
// 是一个类,递归解析
$dependencies[] = $this->build($dependency->name);
}
}
return $dependencies;
}
public function resolveNonClass($parameter)
{
// 有默认值则返回默认值
if ($parameter->isDefaultValueAvailable()) {
return $parameter->getDefaultValue();
}
//没有默认值就发出警告
throw new Exception('参数没又默认值');
}
} //通过Ioc容器获取的
//实例化容器
$app = Container::_ins();
//直接依赖注入
$app->demo1 = 'Demo1';
$demo1 = $app->demo1;
//输出名字是xxx
echo $demo1->Name();
参考资料:
- https://blog.csdn.net/dream_successor/article/details/79078905
- https://blog.csdn.net/a8228560/article/details/79805195
php依赖注入与容器,Container,控制反转的更多相关文章
- 设计模式之————依赖注入(Dependency Injection)与控制反转(Inversion of Controller)
参考链接: 依赖注入(DI) or 控制反转(IoC) laravel 学习笔记 —— 神奇的服务容器 PHP 依赖注入,从此不再考虑加载顺序 名词解释 IoC(Inversion of Contro ...
- .NET CORE学习笔记系列(2)——依赖注入【1】控制反转IOC
原文:https://www.cnblogs.com/artech/p/net-core-di-01.html 一.流程控制的反转 IoC的全名Inverse of Control,翻译成中文就是“控 ...
- 基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转
在前面随笔,我们介绍过这个基于SqlSugar的开发框架,我们区分Interface.Modal.Service三个目录来放置不同的内容,其中Modal是SqlSugar的映射实体,Interface ...
- spring-第一篇之spring核心机制依赖注入(DI)/控制翻转(IoC)
1.spring的核心机制:依赖注入(DI)/控制翻转(IoC) 什么是依赖:A对象需要调用B对象,所以A依赖于B. 什么是注入:A对象注入一个属性B对象. 什么是依赖注入(DI):A对象依赖于B对象 ...
- spring的容器(控制反转、依赖注入)
一.spring的容器 ”容器“是spring的一个重要概念,其主要作用是完成创建成员变量,并完成装配. 而容器的特点”控制反转“和”依赖注入“是两个相辅相成的概念. 控制反转:我们在使用一个类型的实 ...
- Spring_01 spring容器、控制反转(IOC)、依赖注入(DI)
目录 1 什么是spring框架 2 spring框架的特点 3 spring容器 3.1 什么是spring容器 3.2 spring容器创建对象的编程步骤 3.4 spring容器创建对象的方式 ...
- laravel服务容器(IOC控制反转,DI依赖注入),服务提供者,门脸模式
laravel的核心思想: 服务容器: 容器:就是装东西的,laravel就是一个个的对象 放入:叫绑定 拿出:解析 使用容器的目的:这里面讲到的是IOC控制反转,主要是靠第三方来处理具体依赖关系的解 ...
- 自己实现一个IOC(控制翻转,DI依赖注入)容器
1.新建一个控制台应用程序 TestIOC 2.新增一个 IocFactory类 using System; using System.Collections.Generic; using Syste ...
- TypeC一个微软开发的超简单.NET依赖注入/IoC容器
控制反转(IoC,Inversion of Control)是由Martin Fowler总结出来的一种设计模式,用来减少代码间的耦合.一般而言,控制反转分为依赖注入(Dependency Injec ...
随机推荐
- ubuntu 安装flask+nginx+gunicorn 待定
第一步 先检查服务器环境 pip python3 mysql redis 能下就下,该升级就升级 第二步 如果你的flask程序在github上 请使用git clone 地址 下载下来(如果是私 ...
- golang.org/x/sys/unix: unrecognized
安装的过程中报错 : package golang.org/x/sys/unix: unrecognized import path "golang.org/x/sys/unix" ...
- HTML实体符号代码
1. 特色的 © © © 版权标志 | | 竖线,常用作菜单或导航中的分隔符 · · · 圆点,有时被用来作为菜单分隔符 ↑ ↑ ↑ 上箭头,常用作网页“返回页面顶部”标识 € € € 欧元标识 ...
- ico制作工具
因为要满足不同尺寸的图标很多网站生成的ico都是单一尺寸的无法满足特殊要求因此推荐一个ICO制作工具 Axialis IconWorkshop 6.91 下载:https://www.axialis. ...
- Redis基本数据类型、数据持久化、过期策略及淘汰机制
一点技术.技术乐享!!! 如果有人问你:Redis这么快,他的“多线程模式”你了解吗? 请回答他:您是想问Redis这么快,为什么还是单线程模式吗? redis是什么 简单来说redis是C语言开发的 ...
- mvc+ef入门(三)
(1)新建一个DAL层用来放置Accountcontext.cs和Accountinitializer.新建一个models层用来归放sysuser,sysrole和sysuserrole,三个类.( ...
- python基础知识1——简介与入门
什么是Python:Python能做什么:安装与更新:第一个Python程序:变量:pyc字节码:编码:条件和循环:Python运算符:算数,比较,赋值,位,逻辑::::::::::::::::::: ...
- 《HelloGitHub》第 48 期
兴趣是最好的老师,HelloGitHub 就是帮你找到兴趣! 简介 分享 GitHub 上有趣.入门级的开源项目. 这是一个面向编程新手.热爱编程.对开源社区感兴趣 人群的月刊,月刊的内容包括:各种编 ...
- 搭建SQL server AwaysOn集群
1.环境 系统:windows server 2012 R2 数据库版本:SQL server 2012 三台服务器,IP分别是:10.10.10.111,10.10.10.112,10.10.10. ...
- OpenCV-Python 用于角点检测的FAST算法 | 四十一
目标 在本章中, 我们将了解FAST算法的基础知识. 我们将使用OpenCV功能对FAST算法进行探索. 理论 我们看到了几个特征检测器,其中很多真的很棒.但是,从实时应用程序的角度来看,它们不够快. ...