<?php
class Container { private $bindings = [];
private $instances = []; public function getClosure($concrete) {
return function($parameter = []) use($concrete) { # 在这里我们找到了判断初始化函数的契机,利用反射我们可以做很多事,包括我们的问题
# 1.获得一个$concrete类反射
$reflector = new ReflectionClass($concrete);
# 2.判断这个类能否被实例化,例如 private function __construct(){}
if(!$reflector->isInstantiable()) {
throw new Exception("{$concrete} 无法被实例化");
} # 3.获取构造函数反射方法
$constructor = $reflector->getConstructor(); # 4.获取参数列表
$parameters = $constructor->getParameters(); # 5.遍历参数列表
$instancesParams = [];
foreach ($parameters as $_parameter) {
# 如果已经$parameter中已经设置了对应的参数
if(isset($parameter[$_parameter->name])) {
$instancesParams[] = $parameter[$_parameter->name];
continue;
} # 如果没设置判断一下这个参数是否存在默认值
if(!$_parameter->isDefaultValueAvailable()) {
throw new Exception("{$concrete} 无法被实例化,缺少参数{$_parameter->name}");
} $instancesParams[] = $_parameter->getDefaultValue();
} # 这里就需要通过反射来构建对象了
// return new $concrete($parameter);
return $reflector->newInstanceArgs($instancesParams);
};
} public function bind($abstract , $concrete=null, $shared = false)
{
if (is_null($concrete)) {
$concrete = $abstract;
} if (!$concrete instanceof Closure) {
$concrete = $this->getClosure($concrete);
} $this->bindings[$abstract] = [
'concrete' => $concrete,
'shared' => $shared
];
} public function make($abstract ,array $parameters = []) {
if (!isset($this->bindings[$abstract])) {
return false;
} if (isset($this->instances[$abstract])) {
return $this->instances[$abstract];
} # 先获取到具体的类型
$concrete = $this->bindings[$abstract]['concrete'];
# 这里需要思考一下
# 到目前为止我们的$this->bindings[$abstract]['concrete']里存储的都是通过getClosure方法生成的闭包。
# 那么直接在这里判断类型肯定行不通,所以我们跳到getClosure里面去看看
$object = $concrete($parameters);
if($this->bindings[$abstract]['shared']) {
$this->instances[$abstract] = $object;
} return $object;
}
} class Person{
private $name;
private $isProgrammer;
public function __construct($name,$isProgrammer = true) {
$this->name = $name;
$this->isProgrammer = $isProgrammer;
} public function me() {
$message = $this->isProgrammer ? ',Ta是一个程序员' :'';
return "姓名: {$this->name} $message";
}
}
$container = new Container();
$container->bind('Person',null,false);
$p1 = $container->make('Person',[
'name' => 'lilei',
'age'=>10
]); $p2 = $container->make('Person',[
'name' => 'zhangsan',
'age'=>10
]); echo $p1->me();
echo $p2->me(); var_dump($p1,$p2);
var_dump($p1 === $p2);

  

lumen容器模仿的更多相关文章

  1. lumen-ioc容器测试 (2)

    lumen-ioc容器测试 (1) lumen-ioc容器测试 (2) lumen-ioc容器测试 (3) lumen-ioc容器测试 (4) lumen-ioc容器测试 (5) lumen-ioc容 ...

  2. Lumen开发:如何向 IoC 容器中添加自己定义的类

    版权声明:本文为博主原创文章,未经博主允许不得转载. 先在起始文件bootstrap/app.php加上$app->register(App\Providers\User\UserService ...

  3. [转贴]从零开始学C++之STL(二):实现一个简单容器模板类Vec(模仿VC6.0 中 vector 的实现、vector 的容量capacity 增长问题)

    首先,vector 在VC 2008 中的实现比较复杂,虽然vector 的声明跟VC6.0 是一致的,如下:  C++ Code  1 2   template < class _Ty, cl ...

  4. Java入门记(四):容器关系的梳理(上)——Collection

    目录 一.Collection及子类/接口容器继承关系 二.List 2.1 ArrayList 2.1.1 序列化的探讨 2.1.2 删除元素 2.1.3 调整大小 2.2 Vector和Stack ...

  5. 整合Servlet到Spring容器

    有时在Spring(3.2.5)项目中,如果使用到Servlet,可能希望Servlet实例作为bean受Spring容器管理,这样也能自动注入其他需要的bean,查了下,发现只针对过滤器提供了代理类 ...

  6. Java集合容器简介

    Java集合容器主要有以下几类: 1,内置容器:数组 2,list容器:Vetor,Stack,ArrayList,LinkedList, CopyOnWriteArrayList(1.5),Attr ...

  7. Swing 顶层容器

    顶层容器值得是容纳其他容器的容器组件,包括JFrame类,JWindows类,JDialog类,JApplet等.Swing中的顶层容器类Swing提供三个顶层容器类:JFrame,JDialog和J ...

  8. Cocos2d-x中__Dictionary容器以及实例介绍

    __Dictionary类在Cocos2d-x 2.x时代它就是CCDictionary类,它是模仿Objective-C中的NSDictionary类而设计的,通过引用计数管理内存.__Dictio ...

  9. Cocos2d-x中Vector<T>容器以及实例介绍

    Vector<T> 是Cocos2d-x 3.x推出的列表容器,因此它所能容纳的是Ref及子类所创建的对象指针,其中的T是模板,表示能够放入到容器中的类型,在Cocos2d-x 3.x中T ...

随机推荐

  1. 藏在Java数组的背后,你可能忽略的知识点

    目录 引言 概念 区别于C/C++数组 区别于容器 数组特性 随机访问 Java数组与内存 解惑 数组的本质 Java中的数组是对象吗? Java中数组的类型 Java中数组的继承关系 参考资料 引言 ...

  2. MySQL 8 安装教程(个人版)+创建用户

    Mysql 8的安装教程 解压到指定目录如:D:\WinInstall\mysql-8.0.19-winx64这时候你需要在根目录下创建两个文件,分别是data文件夹和my.ini文件,然后使用编辑器 ...

  3. 尤雨溪:TypeScript不会取代JavaScript

    来源 |evrone.com译者 | 核子可乐策划 | 蔡芳芳 近日,Evrone 与 Vue.js 的作者尤雨溪进行了一次访谈,了解他对于无后端与全栈方法.以及 Vue.js 适用场景的看法,还有他 ...

  4. 吴恩达《深度学习》-课后测验-第三门课 结构化机器学习项目(Structuring Machine Learning Projects)-Week1 Bird recognition in the city of Peacetopia (case study)( 和平之城中的鸟类识别(案例研究))

    Week1 Bird recognition in the city of Peacetopia (case study)( 和平之城中的鸟类识别(案例研究)) 1.Problem Statement ...

  5. Hadoop入门学习整理(三)

    1.Hive 的安装 下载tar包,并且要注意和Hadoop版本兼容. 下载  ----->  传输 -------> 解压     即可. 然后配置环境变量和相关配置信息.   参考: ...

  6. 分布式系统监视zabbix讲解五之web监控

    Web 监控 概况 你可以使用 Zabbix 检查几个网站可用性方面. 如果要使用 Web 检测功能,必须在 编译Zabbix 的时候加入 cURL(libcurl) 的支持. 要使用 Web 监控, ...

  7. 最火的开源 IDE介绍与安装教程

    导读:开发C/C++最好的IDE是什么,尤其对于很多初学者来说用什么IDE比较容易上手,本文将做以介绍,并为您演示如何下载与安装. 本文字数:1015,阅读时长大约:10分钟 (一)最火的开源IDE ...

  8. Jmeter引用外部jar包的几种方法

    总结记录下jmeter引用外部jar包的3种方法及其优缺点: 一.测试计划中添加目录或jar包到Classpath 操作:测试计划->添加目录或jar包到Classpath-->浏览导入j ...

  9. Spring学习(三)Spring AOP 简介

    一.简介 定义 aop就是面向切面编程,在数据库事务中切面编程被广泛使用. 在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能. 核心业务:比如登陆,增加数据,删除数据都叫核心业务 周边功能 ...

  10. DC 1-3 靶机渗透

    DC-1靶机 端口加内网主机探测,发现192.168.114.146这台主机,并且开放了有22,80,111以及48683这几个端口. 发现是Drupal框架. 进行目录的扫描: 发现admin被禁止 ...