Laravel实战教程笔记(六) 理解服务容器

原创 木鱼  2017-08-18 12:43  阅读 52 次

引入

大家在看这篇文章之前,要先看一下这篇文章:

Laravel 服务容器实例教程 —— 深入理解控制反转(IoC)和依赖注入(DI) Laravel 服务容器实例教程 —— 深入理解控制反转(IoC)和依赖注入(DI)

这篇文章里面最后的传参有小bug,直接复制本篇的代码测试即可。

内容

本篇文章主要理一下这篇文章的例子的执行流程。

贴出示例,想要测试的话直接复制到任意php文件运行即可。

<?php 

class Container
{
    protected $binds;

    protected $instances;

    public function bind($abstract, $concrete)
    {
    	// 此时闭包函数$concrete是没有调用的,直接赋值。
        if ($concrete instanceof Closure) {
            $this->binds[$abstract] = $concrete;
        } else {
            $this->instances[$abstract] = $concrete;
        }
    }

    public function make($abstract, $parameters = [])
    {
        if (isset($this->instances[$abstract])) {
            return $this->instances[$abstract];
        }

        // 插入当前对象到数组中, 用作闭包函数的第一个参数。
        array_unshift($parameters, $this);
		// 此时$parameters第一个参数是$this, 第二个参数是字符串xpower
        return call_user_func_array($this->binds[$abstract], $parameters);
    }
}

class Superman
{
    protected $module;

    public function __construct($module)
    {
        $this->module = $module;
    }
}

class XPower
{
    public function activate(array $target)
    {
        // 这只是个例子。。具体自行脑补
    }
}

// 创建一个容器(后面称作超级工厂)
$container = new Container;

// 向该 超级工厂添加超人的生产脚本
$container->bind('superman', function($container, $moduleName) {
	// $container是Container的对象 
	// $moduleName是字符串xpower 
	// 再次进入make方法, 查询出xpower并不在$this->instances里面
    // 调用$this->binds('xpower')闭包函数, 生成xpower对象并返回xpower对象
    // 把xpower对象作为new Superman的参数, 进入Superman类,把xpower对象赋值给protected $module;
    return new Superman($container->make($moduleName));
});

// 向该 超级工厂添加超能力模组的生产脚本
$container->bind('xpower', function($container) {
    return new XPower;
});

// 此时superman的参数拥有了xpower对象
$superman_1 = $container->make('superman', array('xpower'));

var_dump($container);
var_dump($superman_1);

里面注释写的也挺详细,这里再整理一下:

<?php 

/**
流程:
1、先把想要得到能力的超人绑定给binds,超人的闭包函数要有参数,用于赋值传递能力。
2、同时把所有的超能力也绑定给binds。
3、调用make把xpower能力赋值给superman的时候,检测出spuerman并不在实例当中。
4、调用superman的闭包函数,把容器对象和能力作为闭包函数的参数。 5、然后superman的闭包函数再次调用make方法,把字符串xpower传参给make方法。
6、同理,make没有检测到xpower的实例。
7、那就调用xpower的闭包函数,生成xpower对象并返回给make方法,make方法接着返回,把xpower的对象返回给superman的闭包函数
8、这样, superman的闭包就得到了xpower对象了,把xpower对象作为参数传给superman类,superman类里面的构造函数__contrust又把xpower对象赋值给属性$module。 这样,superman就能通过$module使用xpower能力了。

*/

本文地址:https://www.m5yu.com/laravel-ioc.html
关注我们:请关注一下我们的微信公众号:扫描二维码,公众号:木鱼博客
版权声明:本文为原创文章,版权归 木鱼 所有,欢迎分享本文,转载请保留出处!
下一篇:已经是最新一篇了

发表评论