着手AllInOne项目之前,把laravel项目运行生命周期研究了一下
$app = require_once __DIR__.'/../bootstrap/app.php';
引入app.php文件。实例化Application类
Application类继承Container,Container统称容器,实质就是把一些类,闭包赋值到类的对应的属性上
//vendor/laravel/framework/src/Illuminate/Foundation/Application.phppublic function __construct($basePath = null){if ($basePath) {$this->setBasePath($basePath);}$this->registerBaseBindings(); $this->registerBaseServiceProviders(); $this->registerCoreContainerAliases(); }
this−>setBasePath(this->setBasePath(this−>setBasePath(basePath); 绑定一些基础属性
$this->registerBaseBindings(); 挂载到容器上bindings属性一些地址映射
$this->registerBaseServiceProviders(); //单例挂载到bindings 一些服务提供者
对应方法
protected function registerBaseServiceProviders(){$this->register(new EventServiceProvider($this));$this->register(new LogServiceProvider($this));$this->register(new RoutingServiceProvider($this)); //挂载路由}
$app->singleton(Illuminate\Contracts\Http\Kernel::class,App\Http\Kernel::class
); //绑定http请求处理程序$app->singleton(Illuminate\Contracts\Console\Kernel::class,App\Console\Kernel::class
);//绑定命令行的一些类$app->singleton(Illuminate\Contracts\Debug\ExceptionHandler::class,App\Exceptions\Handler::class
);//绑定处理异常的一些类
绑定到容器 instances属性上
回到index.php文件
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
//var_dump(Illuminate\Http\Request::capture());
$response = $kernel->handle($request = Illuminate\Http\Request::capture()
);
1.解析绑定到容器上的实例化的类
2.解析请求
handle方法
/*** Handle an incoming HTTP request.** @param \Illuminate\Http\Request $request* @return \Illuminate\Http\Response*/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;}
关键代码:
$response = this−>sendRequestThroughRouter(this->sendRequestThroughRouter(this−>sendRequestThroughRouter(request);
送往管道处理
/*** Send the given request through the middleware / router.** @param \Illuminate\Http\Request $request* @return \Illuminate\Http\Response*/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());}
关键代码:
$this->bootstrap();
这里先进行服务提供者解析处理,接着往下追
/*** Bootstrap the application for HTTP requests.** @return void*/public function bootstrap(){//var_dump($this->bootstrappers());if (! $this->app->hasBeenBootstrapped()) {$this->app->bootstrapWith($this->bootstrappers());}}
关键代码:
this−>app−>bootstrapWith(this->app->bootstrapWith(this−>app−>bootstrapWith(this->bootstrappers());
/*** Run the given array of bootstrap classes.** @param string[] $bootstrappers* @return void*/public function bootstrapWith(array $bootstrappers){$this->hasBeenBootstrapped = true;foreach ($bootstrappers as $bootstrapper) {$this['events']->dispatch('bootstrapping: '.$bootstrapper, [$this]);$this->make($bootstrapper)->bootstrap($this);$this['events']->dispatch('bootstrapped: '.$bootstrapper, [$this]);}}
关键代码:
this−>make(this->make(this−>make(bootstrapper)->bootstrap($this);
执行服务提供者的Register方法 \Illuminate\Foundation\Bootstrap\RegisterProviders::class,
执行服务提供者的boot方法 \Illuminate\Foundation\Bootstrap\BootProviders::class,
/*** Bootstrap the given application.** @param \Illuminate\Contracts\Foundation\Application $app* @return void*/public function bootstrap(Application $app){$app->registerConfiguredProviders();}
/*** Register all of the configured providers.** @return void*/public function registerConfiguredProviders(){$providers = Collection::make($this->config['app.providers'])->partition(function ($provider) {return Str::startsWith($provider, 'Illuminate\\');});$providers->splice(1, 0, [$this->make(PackageManifest::class)->providers()]);(new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath()))->load($providers->collapse()->toArray());}
关键代码:
(new ProviderRepository($this, new Filesystem, this−>getCachedServicesPath()))−>load(this->getCachedServicesPath())) ->load(this−>getCachedServicesPath()))−>load(providers->collapse()->toArray());
到服务提供仓库去执行
/*** Register the application service providers.** @param array $providers* @return void*/public function load(array $providers){$manifest = $this->loadManifest();// First we will load the service manifest, which contains information on all// service providers registered with the application and which services it// provides. This is used to know which services are "deferred" loaders.if ($this->shouldRecompile($manifest, $providers)) {$manifest = $this->compileManifest($providers);}// Next, we will register events to load the providers for each of the events// that it has requested. This allows the service provider to defer itself// while still getting automatically loaded when a certain event occurs.foreach ($manifest['when'] as $provider => $events) {$this->registerLoadEvents($provider, $events);}// We will go ahead and register all of the eagerly loaded providers with the// application so their services can be registered with the application as// a provided service. Then we will set the deferred service list on it.foreach ($manifest['eager'] as $provider) {$this->app->register($provider);}$this->app->addDeferredServices($manifest['deferred']);}
关键代码:
foreach ($manifest[‘eager’] as $provider) {
this−>app−>register(this->app->register(this−>app−>register(provider);
}
最后回到
vendor/laravel/framework/src/Illuminate/Foundation/Application.php中执行register方法
/*** Register a service provider with the application.** @param \Illuminate\Support\ServiceProvider|string $provider* @param bool $force* @return \Illuminate\Support\ServiceProvider*/public function register($provider, $force = false){if (($registered = $this->getProvider($provider)) && ! $force) {return $registered;}// If the given "provider" is a string, we will resolve it, passing in the// application instance automatically for the developer. This is simply// a more convenient way of specifying your service provider classes.if (is_string($provider)) {$provider = $this->resolveProvider($provider);}$provider->register();// If there are bindings / singletons set as properties on the provider we// will spin through them and register them with the application, which// serves as a convenience layer while registering a lot of bindings.if (property_exists($provider, 'bindings')) {foreach ($provider->bindings as $key => $value) {$this->bind($key, $value);}}if (property_exists($provider, 'singletons')) {foreach ($provider->singletons as $key => $value) {$this->singleton($key, $value);}}$this->markAsRegistered($provider);// If the application has already booted, we will call this boot method on// the provider class so it has an opportunity to do its boot logic and// will be ready for any usage by this developer's application logic.if ($this->isBooted()) {$this->bootProvider($provider);}return $provider;}
关键代码:
if (is_string($provider)) {
$provider = this−>resolveProvider(this->resolveProvider(this−>resolveProvider(provider);
}
$provider->register();
boot方法同思想
/*** Boot the application's service providers.** @return void*/public function boot(){if ($this->isBooted()) {return;}// Once the application has booted we will also fire some "booted" callbacks// for any listeners that need to do work after this initial booting gets// finished. This is useful when ordering the boot-up processes we run.$this->fireAppCallbacks($this->bootingCallbacks);array_walk($this->serviceProviders, function ($p) {$this->bootProvider($p);});$this->booted = true;$this->fireAppCallbacks($this->bootedCallbacks);}/*** Boot the given service provider.** @param \Illuminate\Support\ServiceProvider $provider* @return mixed*/protected function bootProvider(ServiceProvider $provider){if (method_exists($provider, 'boot')) {return $this->call([$provider, 'boot']);}}
回到 vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php sendRequestThroughRouter方法
/*** Send the given request through the middleware / router.** @param \Illuminate\Http\Request $request* @return \Illuminate\Http\Response*/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());}
关键代码:
这边就是处理中间件和分发路由了
return (new Pipeline(this−>app))−>send(this->app)) ->send(this−>app))−>send(request)
->through($this->app->shouldSkipMiddleware() ? [] : this−>middleware)−>then(this->middleware) ->then(this−>middleware)−>then(this->dispatchToRouter());
待续…
有错误的地方留言指正