Laravel’s entry file is index.php

$this, $Container, $this, $Container, $this

Registration of basic service providers (Event, log, routing),

Registration of core category names (such as DB, auth, config, Router, etc.)

$app->make(Illuminate\Contracts\Http\Kernel::class) resolves app \Http\ http.php from the container to the actual class

The HANDLE method processes the HTTP request

Is actually an HTTP request processed by the sendRequestThroughRouter in Handle

First, bind the request to the shared instance

Then execute the bootstarp method and run the $bootstrappers given an array of bootstrappers. This is the key. This includes loading configuration files, environment variables, providers for the service provider (in config/app.php), portal, exception handling, and bootappers

After that, it enters the pipeline mode and distributes the user requests after being processed and filtered by the middleware

When a request is distributed, it first looks for a route that matches a given request, and then executes the runRoute method, which actually handles the request with runRouteWithinStack in the runRoute method

Then, through the run method in runRouteWithinStack, the request is allocated to the actual controller and the response is obtained

4. Return the processing result

2, detailed source analysis 1, register automatic loader, automatic file loading

require __dir__.'/.. /vendor/autoload.php';Copy the code

Create an instance of the Application Container (which inherits from the Container class) and bind the core (Web, command line, exception) so that they can be resolved as needed

$app = require_once __DIR__.'/.. /bootstrap/app.php';Copy the code

App.php file is as follows:

<? [3] $app = new Illuminate\Foundation\Application($_ENV['APP_BASE_PATH']?? dirname(__DIR__) ); $app->singleton(Illuminate\Contracts\Http\ kernel ::class, app \Http\ kernel ::class); $app->singleton(Illuminate\Contracts\Console\ kernel ::class, app \Console\ kernel ::class); Kernel $app->singleton(Illuminate\Contracts\Debug\ExceptionHandler::class, app \Exceptions\Handler::class); Return $app;Copy the code

3. In the constructor that creates the Application instance (application.php), register the base binding into the container, register all the base service providers, and register the core class names in the container

Public function __construct($basePath = null) {$this->registerBaseBindings(); / / register all basic service provider [3.2] $this - > registerBaseServiceProviders (); / / registered in container core category name [3.3] $this - > registerCoreContainerAliases (); }Copy the code

3.1. Register the base binding with the container

static::setInstance($this); $this->instance('app', $this); $this->instance(Container::class, $this); $this->singleton(Mix::class); $this->instance(PackageManifest::class, new PackageManifest( new Filesystem, $this->basePath(), $this->getCachedPackagesPath() )); # instance.instance (); To register as a shared instance, the Singleton method is to... Register as a share bindingCopy the code

3.2. Register all basic service providers (events, logs, routes)

protected function registerBaseServiceProviders()
{
    $this->register(new EventServiceProvider($this));
    $this->register(new LogServiceProvider($this));
    $this->register(new RoutingServiceProvider($this));
}
Copy the code

3.3. Register the core category name in the container

This completes the auto-loading of classes, service provider registration, binding of core classes, and binding of basic registration

Index.php // 5.1$kernel = $app->make(Illuminate\Contracts\Http\ kernel ::class); $response = $kernel->handle($request = Illuminate\Http\ request ::capture());Copy the code

5.1 The make method parses the given value from the container

kernel =

kernel=app->make(Illuminate\Contracts\Http\Kernel::class);

$app = require_once __DIR__.’/.. /bootstrap/app.php’; The binding refers to the App/Http/Kernel::class class

5.2 HTTP requests are processed here

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);
Copy the code

If you look at the $kernel class App\Http\ kernel.php, you can see that it only defines middleware content, and there is no handle method

Let’s go to its parent class, use Illuminate\Foundation\Http\Kernel as HttpKernel; If you look for the handle method, you can see that the handle method looks like this

Public function handle ($request) {try {/ / way deceive, don't pay any attention here $request - > enableHttpMethodParameterOverride (); [6] $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; }Copy the code

6. Handle HTTP requests (bind the request to a shared instance and process user requests using pipe mode)

Vendor/laravel/framework/SRC/Illuminate/Foundation/Http/Kernel. The handle method of PHP / / at the core of processing $response = Http requests $this->sendRequestThroughRouter($request);Copy the code

Enter the sendRequestThroughRouter method

Protected function sendRequestThroughRouter($this->app->instance('request', $this->app->instance) $request); / / will be asked to request from the appearance of the parsed examples to clear (as has been bound to the Shared instance, there is no need to waste resources) Facade: : clearResolvedInstance (" request "); $this->bootstrap(); [7, 8] // Enter the pipeline mode, through the middleware, Return ($this->app) ->send($request) -> Through ($this->app->shouldSkipMiddleware()? [] : $this->middleware) ->then($this->dispatchToRouter()); }Copy the code

7. In the bootstrap method, run the given bootstrap class array $bootstrappers, load the configuration file, environment variables, service provider, front, exception handling, bootstrap provider, A very important step position in vendor/laravel/framework/SRC/Illuminate/Foundation/Http/Kernel. The PHP

/** * Bootstrap the application for HTTP requests. * * @return void */ public function bootstrap() { if (! $this->app->hasBeenBootstrapped()) { $this->app->bootstrapWith($this->bootstrappers()); }} /** * Run the given array of bootstrappers ** @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]); } } /** * Get the bootstrap classes for the application. * * @return array */ protected function bootstrappers() { return $this->bootstrappers; } /** * Application bootloader class ** @var array */ protected $bootstrappers = [// load environment variables \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class, / / loaded config configuration file [key], Illuminate, Foundation, the Bootstrap \ LoadConfiguration: : class, // Load exception handling \Illuminate\Foundation\Bootstrap\HandleExceptions::class, // Load the facade register \Illuminate\Foundation\Bootstrap\RegisterFacades::class, / / load in the config/app. In PHP will defined in an array of services, Illuminate, Foundation, 8 key 】 【 the Bootstrap \ RegisterProviders: : class, // Illuminate/Foundation/Bootstrap/BootProviders::class,];Copy the code

Load the service defined in the providers array in config/app.php

Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Bus\BusServiceProvider::class, Illuminate\Cache\CacheServiceProvider::class, Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, Illuminate\Cookie\CookieServiceProvider::class, Illuminate\Database\DatabaseServiceProvider::class, Illuminate\Encryption\EncryptionServiceProvider::class, Illuminate\Filesystem\FilesystemServiceProvider::class, Illuminate\Foundation\Providers\FoundationServiceProvider::class, Illuminate\Hashing\HashServiceProvider::class, Illuminate\Mail\MailServiceProvider::class, Illuminate\Notifications\NotificationServiceProvider::class, Illuminate\Pagination\PaginationServiceProvider::class, Illuminate\Pipeline\PipelineServiceProvider::class, Illuminate\Queue\QueueServiceProvider::class, Illuminate\Redis\RedisServiceProvider::class, Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, Illuminate\Session\SessionServiceProvider::class, Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, App\Providers\AppServiceProvider::class, App\Providers\AuthServiceProvider::class, App\Providers\EventServiceProvider::class, App \ will \ RouteServiceProvider: : class, / * * * yourself added service provider * / \ App \ will \ HelperServiceProvider: : class,Copy the code

As you can see, the common Redis, session, queue, auth, database, Route and other services are loaded here

9. Use pipeline mode to process user requests, which are processed by middleware first

Return (new Pipeline($this->app)) ->send($this->app) $this->app->shouldSkipMiddleware()? [] : $this->middleware) ->then($this->dispatchToRouter()); } app/Http/ kernel.php /** * Global Http middleware for your application ** These middleware are run during every request to your application. ** @var array */ protected $middleware = [ \App\Http\Middleware\TrustProxies::class, \App\Http\Middleware\CheckForMaintenanceMode::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, ];Copy the code

10. After being processed by the middleware, the request is distributed (including finding the matching route).

/** * 10.1 Send a given Request via middleware/router ** @param \Illuminate\Http\Request $Request * @return \Illuminate\Http\Response */ protected function sendRequestThroughRouter($request) { ... return (new Pipeline($this->app)) ... $this->dispatchToRouter(); } /** * 10.2 routing dispatcher callback ** @return \Closure */ protected function dispatchToRouter() {return function ($request) { $this->app->instance('request', $request); Return $this->router->dispatch($request); }; } /** * 10.3 Send the Request to the application ** @param \Illuminate\Http\Request $Request * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse */ public function dispatch(Request $request) { $this->currentRequest = $request; return $this->dispatchToRoute($request); } /** * 10.4 Assign the Request to the route and return the response [focus on runRoute method] ** @param \Illuminate\Http\Request $Request * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse */ public function dispatchToRoute(Request $request) { // return  $this->runRoute($request, $this->findRoute($request)); } /** * 10.5 Find a Route that matches a given Request ** @param \Illuminate\Http\Request $Request * @return \Illuminate\Routing\Route */ protected function findRoute($request) { $this->current = $route = $this->routes->match($request); $this->container->instance(Route::class, $route); return $route; } /** * 10.6 Find the first Route that matches a given Request ** @param \Illuminate\Http\Request $Request * @return \Illuminate\Routing\Route ** @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException */ public function match(Request $request) { // $this->get($request->getMethod()); $routes = $this->get($request->getMethod()); $route = $this->matchAgainstRoutes($routes, $request); if (! is_null($route)) { return $route->bind($request); } $others = $this->checkForAlternateVerbs($request); if (count($others) > 0) { return $this->getRouteForMethods($request, $others); } throw new NotFoundHttpException; }Copy the code

At this point, you have found a route that matches the request, and then you will run the runRoute method in 10.4

/** * 10.4 Assign the Request to the route and return the response ** @param \Illuminate\Http\Request $Request * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse */ public function dispatchToRoute(Request $request) { return $this->runRoute($request, $this->findRoute($request)); } /** * 10.7 return the response to the given Route ** @param \Illuminate\Http\Request $Request * @param \Illuminate\Routing\Route $Route * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse */ protected function runRoute(Request $request, Route $route) { $request->setRouteResolver(function () use ($route) { return $route; }); $this->events->dispatch(new Events\RouteMatched($route, $request)); return $this->prepareResponse($request, $this->runRouteWithinStack($route, $request) ); } /** * Run the given route within a Stack "onion" instance. ** @param \Illuminate\Routing\ route $route * @param \Illuminate\Http\Request $request * @return mixed */ protected function runRouteWithinStack(Route $route, Request $request) { $shouldSkipMiddleware = $this->container->bound('middleware.disable') && $this->container->make('middleware.disable') === true; $middleware = $shouldSkipMiddleware ? [] : $this->gatherRouteMiddleware($route); return (new Pipeline($this->container)) ->send($request) ->through($middleware) ->then(function ($request) use ($route) { return $this->prepareResponse( $request, $route->run() ); }); }Copy the code

As you can see, one of the methods in 10.7 is the prepareResponse, which creates an instance of the response from a given value, and the runRouteWithinStack method runs the route on the stack. That is, HTTP requests and responses are done here.