着手AllInOne项目之前,把laravel项目运行生命周期研究了一下
$app = require_once __DIR__.'/../bootstrap/app.php';
引入app.php文件。实例化Application类
Application类继承Container,Container统称容器,实质就是把一些类,闭包赋值到类的对应的属性上
//vendor/laravel/framework/src/Illuminate/Foundation/Application.php
public function __construct($basePath = null)
{
if ($basePath) {
$this->setBasePath($basePath);
}
$this->registerBaseBindings();
$this->registerBaseServiceProviders();
$this->registerCoreContainerAliases();
}
t
h
i
s
−
>
s
e
t
B
a
s
e
P
a
t
h
(
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 = t h i s − > s e n d R e q u e s t T h r o u g h R o u t e r ( 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());
}
}
关键代码:
t h i s − > a p p − > b o o t s t r a p W i t h ( 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]);
}
}
关键代码:
t h i s − > m a k e ( 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, t h i s − > g e t C a c h e d S e r v i c e s P a t h ( ) ) ) − > l o a d ( 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) {
t h i s − > a p p − > r e g i s t e r ( 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 = t h i s − > r e s o l v e P r o v i d e r ( 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( t h i s − > a p p ) ) − > s e n d ( this->app)) ->send( this−>app))−>send(request)
->through($this->app->shouldSkipMiddleware() ? [] : t h i s − > m i d d l e w a r e ) − > t h e n ( this->middleware) ->then( this−>middleware)−>then(this->dispatchToRouter());
待续…
有错误的地方留言指正