1.3 - Laravel 5.6 - Callbacks 回调函数机制

回调函数在容器中,用的也很多。先说作用,在某些操作的节点,比如解析后,插入必要的一些操作。感觉就像hook和事件Event一样。

在container中,有好几种callbacks

protected $reboundCallbacks = [];//所有注册的回调
protected $globalResolvingCallbacks = [];//所有全局解析回调
protected $globalAfterResolvingCallbacks = [];//所有全局解析之后回调
protected $resolvingCallbacks = [];//所有类的解析回调
protected $afterResolvingCallbacks = [];//所有类的解析之后回调

他们分别出现在不一样的地方被调用。

我们以第一个rebound举例: 其他几个大同小异。

触发rebound()回调函数的源码如下:

1.解析当前的对象

2.然后查看当前容器中是否存在对应的rebound回调函数,如果有,遍历所有对应的回调函数,使用call_user_func执行回调函数。


protected function rebound($abstract)
{
    $instance = $this->make($abstract);
    foreach ($this->getReboundCallbacks($abstract) as $callback) {
        call_user_func($callback, $this, $instance);
    }
}

2.1看下getReboundCallbacks,获取对应所有的回调函数是通过reboundCallbacks数组获得。源码如下:


protected function getReboundCallbacks($abstract)
{
    if (isset($this->reboundCallbacks[$abstract])) {
        return $this->reboundCallbacks[$abstract];
    }
    return [];
}

3.最后这个rebound()方法我们上一章1.2中知道,它会在extend绑定完成后会调用触发。

回调函数的绑定

我们上面涉及了调用,我们下面看下如何绑定。

回调函数的绑定是通过函数rebinding处理的,很简单,就是把对应的回调函数存入reboundCallbacks数组。

最后一句,如果这个对象已经绑定过了,还会贴心的返回这个对象。

public function rebinding($abstract, Closure $callback)
{
    $this->reboundCallbacks[$abstract = $this->getAlias($abstract)][] = $callback;
    if ($this->bound($abstract)) {
        return $this->make($abstract);
    }
}

总结

回调函数也很简单,我们只要知道在这个例子中,他通过方法rebinding,把回调函数存储在数组reboundCallbacks中,然后使用rebound以及其他几个函数在不同的地方触发。(extend扩展中触发了。)

实测例子

在extend之前rebinding一个回调函数,当extend完成,会输出this is rebinding callbacks

class ExampleTest extends TestCase
{
    public function testClosure()
    {
        app()->bind('money', Money::class);
        app()->rebinding('money', function(){
            var_dump("this is rebinding callbacks");
        });

        app()->extend('money',function(){
            return new Dollar();
        });

        $boss= app()->make('money');
        $output = $boss->getAmount();
        $this->assertEquals($output, 1);
    }
}

//

class Money
{
    public function getAmount(){
        return 100;
    }
}

class Dollar extends Money
{
    public function getAmount()
    {
        return 1;
    }
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!