1、public\index.php中调用了bootstrap\app.php:
$app = require_once __DIR__.'/../bootstrap/app.php';
2、bootstrap\app.php中调用了vendor\laravel\framework\src\Illuminate\Foundation\Application.php:
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
然后再vendor\laravel\framework\src\Illuminate\Foundation\Application.php构造函数中调用了registerCoreContainerAliases方法设置了别名,如'db' => [\Illuminate\Database\DatabaseManager::class]:
public function __construct($basePath = null)
{
if ($basePath) {
$this->setBasePath($basePath);
}
$this->registerBaseBindings();
$this->registerBaseServiceProviders();
$this->registerCoreContainerAliases();
}
3、bootstrap\app.php中调用了singleton函数将类App\Http\Kernel绑定到Illuminate\Contracts\Http\Kernel中:
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
4、public\index.php中调用了make方法生成类App\Http\Kernel的实例:
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
5、public\index.php中调用了类App\Http\Kernel实例的父类Illuminate\Foundation\Http\Kernel的handle方法:
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
在handle方法中调用了sendRequestThroughRouter方法:
public function handle($request)
{
try {
$request->enableHttpMethodParameterOverride();
$response = $this->sendRequestThroughRouter($request);
} catch (Exception $e) {
$this->reportException($e);
$response = $this->renderException($request, $e);
} catch (Throwable $e) {
$this->reportException($e = new FatalThrowableError($e));
$response = $this->renderException($request, $e);
}
$this->app['events']->dispatch(
new Events\RequestHandled($request, $response)
);
return $response;
}
在sendRequestThroughRouter方法中调用了bootstrap方法:
protected function sendRequestThroughRouter($request)
{
$this->app->instance('request', $request);
Facade::clearResolvedInstance('request');
$this->bootstrap();
return (new Pipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
}
在bootstrap方法中调用了容器vendor\laravel\framework\src\Illuminate\Foundation\Application.php中的bootstrapWith方法执行了$bootstrappers中所有类的bootstrap方法,其中包含\Illuminate\Foundation\Bootstrap\RegisterFacades类:
protected $bootstrappers = [
\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
\Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
\Illuminate\Foundation\Bootstrap\HandleExceptions::class,
\Illuminate\Foundation\Bootstrap\RegisterFacades::class,
\Illuminate\Foundation\Bootstrap\RegisterProviders::class,
\Illuminate\Foundation\Bootstrap\BootProviders::class,
];
public function bootstrap()
{
if (! $this->app->hasBeenBootstrapped()) {
$this->app->bootstrapWith($this->bootstrappers());
}
}
protected function bootstrappers()
{
return $this->bootstrappers;
}
public function bootstrapWith(array $bootstrappers)
{
$this->hasBeenBootstrapped = true;
foreach ($bootstrappers as $bootstrapper) {
$this['events']->fire('bootstrapping: '.$bootstrapper, [$this]);
$this->make($bootstrapper)->bootstrap($this);
$this['events']->fire('bootstrapped: '.$bootstrapper, [$this]);
}
}
6、vendor\laravel\framework\src\Illuminate\Foundation\Bootstrap\RegisterFacades.php中的bootstrap方法中setFacadeApplication方法设置容器信息:
public function bootstrap(Application $app)
{
Facade::clearResolvedInstances();
Facade::setFacadeApplication($app);
AliasLoader::getInstance($app->make('config')->get('app.aliases', []))->register();
}
7、在控制器中调用DB对应的方法时:
use Illuminate\Support\Facades\DB;
$data = DB::connection('数据库连接名')->select('sql语句');
由于没有相应的静态函数,首先会调用DB的父类Illuminate\Support\Facades\Facade中的__callStatic方法:
public static function __callStatic($method, $args)
{
$instance = static::getFacadeRoot();
if (! $instance) {
throw new RuntimeException('A facade root has not been set.');
}
return $instance->$method(...$args);
}
在__callStatic方法中通过static::getFacadeRoot()方法实例化Illuminate\Support\Facades\DB::getFacadeAccessor()别名对应的类,然后通过$instance->$method(...$args)调用实例中对应的方法:
protected static function getFacadeAccessor()
{
return 'db';
}