<?php 

class People
{
public $dog = null; public function __construct()
{
$this->dog = new Dog();
} public function putDog(){
return $this->dog->dogCall();
} } class Dog{
public function dogCall(){
return 'go to home....';
}
} class Container
{
/**
* 容器绑定,用来装提供的实例或者 提供实例的回调函数
* @var array
*/
public $building = []; /**
* 注册一个绑定到容器
*/
public function bind($abstract, $concrete = null, $shared = false)
{
if(is_null($concrete)){
$concrete = $abstract;
} if(!$concrete instanceOf Closure){
$concrete = $this->getClosure($abstract, $concrete); } $this->building[$abstract] = compact("concrete", "shared"); print_r($this->building);
// $res = ($this->building)['Dog']['concrete'];
// print_r($res);die;
// var_dump($res instanceof Closure);die; } //注册一个共享的绑定 单例
public function singleton($abstract, $concrete, $shared = true){
$this->bind($abstract, $concrete, $shared);
} /**
* 默认生成实例的回调闭包
*
* @param $abstract
* @param $concrete
* @return Closure
*/
public function getClosure($abstract, $concrete)
{
return function($c) use($abstract, $concrete){ $method = ($abstract == $concrete)? 'build' : 'make'; print_r($method.PHP_EOL); return $c->$method($concrete);
};
} /**
* 生成实例
*/
public function make($abstract)
{
$concrete = $this->getConcrete($abstract); $data = $this->isBuildable($concrete, $abstract); // print_r($concrete);die; if( $data ){ $object = $this->build($concrete); }else{
$object = $this->make($concrete);
} return $object;
} /**
* 获取绑定的回调函数
*/
public function getConcrete($abstract)
{
// if(! isset($this->building[$abstract]) ){
// return $abstract;
// } if( is_object($abstract) ){
return $abstract;
} return $this->building[$abstract]['concrete'];
} /**
* 判断 是否 可以创建服务实体
*/
public function isBuildable($concrete, $abstract)
{
return $concrete === $abstract || $concrete instanceof Closure;
} /**
* 根据实例具体名称实例具体对象
*/
public function build($concrete)
{
if($concrete instanceof Closure){ return $concrete($this);
} //创建反射对象
$reflector = new \ReflectionClass($concrete); print_r($reflector); if( ! $reflector->isInstantiable()){
//抛出异常
throw new \Exception('error.');
} $constructor = $reflector->getConstructor(); print_r($constructor);
if(is_null($constructor)){
return new $concrete;
} $dependencies = $constructor->getParameters(); print_r($dependencies); $instance = $this->getDependencies($dependencies); print_r( $reflector->newInstanceArgs($instance) ); return $reflector->newInstanceArgs($instance); } //通过反射解决参数依赖
public function getDependencies(array $dependencies)
{
$results = [];
foreach( $dependencies as $dependency ){
$results[] = is_null($dependency->getClass())
?$this->resolvedNonClass($dependency)
:$this->resolvedClass($dependency);
} return $results;
} //解决一个没有类型提示依赖
public function resolvedNonClass(ReflectionParameter $parameter)
{
if($parameter->isDefaultValueAvailable()){
return $parameter->getDefaultValue();
}
throw new \Exception('error_one.'); } //通过容器解决依赖
public function resolvedClass(ReflectionParameter $parameter)
{
return $this->make($parameter->getClass()->name); } } $app = new Container(); $app->bind('Dog','Dog');
$app->bind('People', 'People');
$people = $app->make('People');
echo $people->putDog(); ?>

最新文章

  1. Mina传输大数组,多路解码,粘包问题的处理
  2. ASP: VS2015 + IIS Express 10 学习笔记
  3. 160905、c3p0详细配置
  4. Linux驱动设计—— 中断与时钟
  5. maven安装报错
  6. Android Https相关完全解析 当OkHttp遇到Https
  7. Framework 类库的事件编程
  8. (转)Ehcache作为分布式缓存的研究
  9. 转:Stack Overflow通过关注性能,实现单块应用架构的扩展能力
  10. angular 基础练习
  11. 通过读取配置文件,启动mongodb
  12. 延迟确认和Nagle算法
  13. 如何搜索 git 提交记录
  14. 30个极大提高开发效率的vscode插件
  15. QT 5 安装 vs2017 后,出现找不到 rc.exe 问题
  16. mysql 原理 ~ binlog
  17. 以太坊智能合约开发,Web3.js API 中文文档 ethereum web3.js入门说明
  18. 闹钟AlarmAndMusic 和支持播放音乐效果《IT蓝豹》
  19. Shape流动效果
  20. [leetcode]179. Largest Number最大数

热门文章

  1. Spring IOC 源码解析(持续)
  2. [转][修]利用matlab绘制地图上的点、线、面
  3. 7.scala:继承
  4. 【Network Architecture】Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning(转)
  5. 数据结构——堆(Heap)大根堆、小根堆
  6. C# Memcached 缓存
  7. shell脚本中case select 的使用
  8. Flutter新手第一个坑:Could not find com.android.tools.lint:lint-gradle:26.1.1.
  9. Apache 2 移植到Arm开发板
  10. Linux下部署 jar包