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 协议》,转载必须注明作者和本文链接
推荐文章: