<?php 

 //容器类装实例或提供实例的回调函数
class Container { protected $bindings = []; //绑定接口和生成相应实例的回调函数
public function bind($abstract, $concrete=null, $shared=false) { //如果提供的参数不是回调函数,则产生默认的回调函数
if(!$concrete instanceof Closure) {
$concrete = $this->getClosure($abstract, $concrete);
} $this->bindings[$abstract] = compact('concrete', 'shared');
} //默认生成实例的回调函数
protected function getClosure($abstract, $concrete) { return function($c) use ($abstract, $concrete) {
$method = ($abstract == $concrete) ? 'build' : 'make';
return $c->$method($concrete);
}; } public function make($abstract) {
$concrete = $this->getConcrete($abstract); if($this->isBuildable($concrete, $abstract)) {
$object = $this->build($concrete);
} else {
$object = $this->make($concrete);
} return $object;
} protected function isBuildable($concrete, $abstract) {
return $concrete === $abstract || $concrete instanceof Closure;
} //获取绑定的回调函数
protected function getConcrete($abstract) {
if(!isset($this->bindings[$abstract])) {
return $abstract;
} return $this->bindings[$abstract]['concrete'];
} //实例化对象
public function build($concrete) { if($concrete instanceof Closure) {
return $concrete($this);
} $reflector = new ReflectionClass($concrete);
if(!$reflector->isInstantiable()) {
echo $message = "Target [$concrete] is not instantiable";
} $constructor = $reflector->getConstructor();
if(is_null($constructor)) {
return new $concrete;
} $dependencies = $constructor->getParameters();
$instances = $this->getDependencies($dependencies); return $reflector->newInstanceArgs($instances);
} //解决通过反射机制实例化对象时的依赖
protected function getDependencies($parameters) {
$dependencies = [];
foreach($parameters as $parameter) {
$dependency = $parameter->getClass();
if(is_null($dependency)) {
$dependencies[] = NULL;
} else {
$dependencies[] = $this->resolveClass($parameter);
}
} return (array)$dependencies;
} protected function resolveClass(ReflectionParameter $parameter) {
return $this->make($parameter->getClass()->name);
} } class Traveller { protected $trafficTool; public function __construct(Visit $trafficTool) {
$this->trafficTool = $trafficTool;
} public function visitTibet() {
$this->trafficTool->go();
} } interface Visit {
public function go();
} class Train implements Visit { public function go() {
echo "go to Tibet by train !!!";
} } $app = new Container();
$app->bind("Visit", "Train");
$app->bind("traveller", "Traveller"); $tra = $app->make("traveller");
$tra->visitTibet();

laravel框架中容器类简化代码-摘自某书的更多相关文章

  1. Laravel框架中的数据库CURD操作、连贯操作、链式操作的用法

    Laravel是一套简洁.优雅的PHP Web开发框架(PHP Web Framework).它可以让你从面条一样杂乱的代码中解脱出来:它可以帮你构建一个完美的网络APP,而且每行代码都可以简洁.富于 ...

  2. laravel框架中超实用的功能介绍

    本篇文章给大家带来的内容是关于laravel框架中超实用的功能介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 让lumen的dd() dump()像laravel一样优雅 1 c ...

  3. Laravel框架中Echo的使用过程

    今天的这篇文章中给大家分享关于laravel框架中echo的使用,文章的内容是一步一步来的,用了16步走完一个过程,过程很清晰,希望可以帮助到有需要的朋友吧.话不多说,直接看内容.官方文档推荐使用 P ...

  4. 在laravel框架中使用mq

    本文写于2018-11-28 1.部署laravel项目 https://github.com/laravel/laravel  通过git克隆项目,或者下载zip包然后解压等方式都可以把larave ...

  5. laravel框架中所用到的依赖注入

    用Laravel开发前前后后有2个月左右了,之前一直写Java,就像找到Java和PHP之前的共同点,用Java的某些原理去理解PHP会发现还是有很多共通之处的.Java的依赖注入已经是一个很常见的概 ...

  6. laravel框架中Job和事件event的解析

    本篇文章给大家带来的内容是关于laravel框架中Job和事件event的解析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 在做项目的时候,一直对Job和Event有个疑惑.感觉两 ...

  7. laravel框架中使用QueryList插件采集数据

    laravel框架中使用queryList 采集数据 采集数据对我们来说真家常便饭,那么苦苦的写正则采集那么一点点东西,花费了自己大把的时间和精力而且没有一点技术含量,这个时候就是使用我们的好搭档Qu ...

  8. Laravel框架中的make方法详解

    为什么网上已经有这么多的介绍Laravel的执行流程了,Laravel的容器详解了,Laravel的特性了,Laravel的启动过程了之类的文章,我还要来再分享呢? 因为,每个人的思维方式和方向是不一 ...

  9. Laravel框架中实现supervisor执行异步进程

    问题描述:在使用Laravel框架实现动态网页时,若有些操作计算量较大,为了不影响用户体验,往往需要使用异步方式去处理.这里使用supervisor和laravel自带的queues实现. Super ...

随机推荐

  1. Android开发学习之路-使用annotationProcessor配置Butterknife

    Apt工具的作者宣布了不再维护该工具了,而且Android Studio也有了自己的插件,并且可以通过gradle来简单的配置. 其实用Butterknife的都知道,没有apt,onClick绑定不 ...

  2. SQL Server 监控系列(文章索引)

    一.前言(Introduction) SQL Server监控在很多时候可以帮助我们了解数据库做了些什么,比如谁谁在什么时候修改了表结构,谁谁在删除了某个对象,当这些事情发生了,老板在后面追着说这是谁 ...

  3. 在SQL Server中为什么不建议使用Not In子查询

        在SQL Server中,子查询可以分为相关子查询和无关子查询,对于无关子查询来说,Not In子句比较常见,但Not In潜在会带来下面两种问题: 结果不准确 查询性能低下       下面 ...

  4. Android自定义控件之自定义属性

    前言: 上篇介绍了自定义控件的基本要求以及绘制的基本原理,本篇文章主要介绍如何给自定义控件自定义一些属性.本篇文章将继续以上篇文章自定义圆形百分比为例进行讲解.有关原理知识请参考Android自定义控 ...

  5. 计算机程序的思维逻辑 (51) - 剖析EnumSet

    上节介绍了EnumMap,本节介绍同样针对枚举类型的Set接口的实现类EnumSet.与EnumMap类似,之所以会有一个专门的针对枚举类型的实现类,主要是因为它可以非常高效的实现Set接口. 之前介 ...

  6. 深入理解Sqlserver文件存储之页和应用 (转)

    我们每天都在使用数据库,我们部门使用最多的关系数据库有Sqlserver,Oracle,有没有想过这些数据库是怎么存放到操作系统的文件中的?有时候为了能够设计出最优的表结构,写出高性能的Sqlserv ...

  7. js实现StringBuffer

    实现 function StringBuffer() { this.__strings__ = []; }; StringBuffer.prototype.Append = function (str ...

  8. 使用OAuth、Identity创建WebApi认证接口供客户端调用

    前言 现在的web app基本上都是前后端分离,之前接触的大部分应用场景最终产品都是部署在同一个站点下,那么随着WebApi(Restful api)的发展前后端实现的完全分离,前端不在后端框架的页面 ...

  9. 【Spring-web】RestTemplate源码学习——梳理内部实现过程

    2016-12-28 by 安静的下雪天  http://www.cnblogs.com/quiet-snowy-day/p/6228198.html  提示:使用手机浏览时请注意,图多费流量. 本篇 ...

  10. “NOSQL” 杂谈

    引言: nosql 的兴起和革命,在我看来已经开始逐渐影响到了传统的sql的地位,但是仅仅是影响而已,取代是不太可能的. 正文: 两年前,一个偶然的机会开始接触到 nosql ( mongodb ). ...