共计 2066 个字符,预计需要花费 6 分钟才能阅读完成。
参考资料:
php:laravel 底层外围代码剖析之 make 办法的实现
Laravel 加载过程 —make 办法
实例化 Illuminate\Contracts\Http\Kernel
make 办法
/public/index.php
$app = require_once __DIR__.'/../bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$app->make() => 父类 Application 中的 make() => resolve() 办法
resolve 办法
vendor/laravel/framework/src/Illuminate/Container/Container.php
/**
* 第一次调用
* $abstract Illuminate\Contracts\Http\Kernel::class
* $concrete 匿名函数
*
* 第二次调用
* $abstract 'App\Http\Kernel'
* $concrete 'App\Http\Kernel'(getConcrete 办法返回)* 执行 build() 办法获取 App\Http\Kernel 的实例化对象,返回给 getClosure()
*/
protected function resolve($abstract, $parameters = [], $raiseEvents = true)
{
...
// 依据 $abstract 从 bindings 数组中获取 $concrete 匿名函数
$concrete = $this->getConcrete($abstract);
// 判断 $concrete 和 $abstract 是否雷同,或者 $concrete 是一个匿名函数
if ($this->isBuildable($concrete, $abstract)) {
// 实例化 $concrete 的类
$object = $this->build($concrete);
} else {
// 递归执行 make
$object = $this->make($concrete);
}
...
}
getClosure() 办法递归调用
/**
* 第一次调用
* $abstract 'Illuminate\Contracts\Http\Kernel'
* $concrete 'App\Http\Kernel'
*
* 第二次调用
* 获取 App\Http\Kernel 的实例,向上返回给 build() 办法
*/
protected function getClosure($abstract, $concrete)
{return function ($container, $parameters = []) use ($abstract, $concrete) {if ($abstract == $concrete) {return $container->build($concrete);
}
return $container->resolve($concrete, $parameters, $raiseEvents = false);
};
}
build 办法
vendor/laravel/framework/src/Illuminate/Container/Container.php
/**
* 第一次调用
* $concrete 匿名函数
*
* 第二次调用
* $concrete 'App\Http\Kernel'
* 执行反射,获取 App\Http\Kernel 类的实例化对象
* 返回给 resolve() 办法
*/
public function build($concrete)
{if ($concrete instanceof Closure) {//bind() 办法中 $concrete = $this->getClosure($abstract, $concrete);
return $concrete($this, $this->getLastParameterOverride());
}
$reflector = new ReflectionClass($concrete);
if (! $reflector->isInstantiable()) {return $this->notInstantiable($concrete);
}
$this->buildStack[] = $concrete;
$constructor = $reflector->getConstructor();
if (is_null($constructor)) {array_pop($this->buildStack);
return new $concrete;
}
$dependencies = $constructor->getParameters();
$instances = $this->resolveDependencies($dependencies);
array_pop($this->buildStack);
return $reflector->newInstanceArgs($instances);
}
正文完