You probably know this already, but for those of you who don't get it yet, a web server's job is pretty simple; it listens to requests, runs a program, and then sends the output of that program as a response. If you look deeper into this simple task you can find many complicated stuff but that's not what we're here to discuss.
You point your client (a browser for example) to google.com and the program on the server looks at the given request and prepares a proper response for you:
This looks simple, no matter how complicated a program is the end result is a response that's sent to the client. Let's look at the program called Laravel that your server is running:
$app = new Illuminate\Foundation\Application( dirname(__DIR__) ); // Bind Important Interfaces To The Container $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); $response = $kernel->handle( $request = Illuminate\Http\Request::capture() ); $response->send(); $kernel->terminate($request, $response);
In this program an
Application instance is created which we use to create an instance of
Kernel; the request is captured from the server then the Kernel handles it and prepares a response. Just before the program finishes, the response is sent to the client, and finally the kernel terminates and the script exits.
Every magical thing that you love about laravel happens inside
The Service Container
Laravel has a powerful service container that manages the application's classes' dependencies. It learns how an instance of a class can be created and each time you want an instance you can just get it from the container.
In the code above
$app holds an instance of that container, and after we acquire that instance Laravel registers the Kernel binding along with some other bindings:
$app->singleton( Illuminate\Contracts\Http\Kernel::class, App\Http\Kernel::class );
So later in the script when we ask for
Illuminate\Contracts\Http\Kernel, the containers gives us an instance of
We're not going to look into the container in this dive, but the container is used a lot in the Laravel core so I thought you should be familiar with what it does.
Back to the Kernel
handle() method of the
Http\Kernel sends your request through the router and handles any exceptions that might rise. However, before sending to the router we need to prepare the application, calling the
bootstrap() method will run the code needed for that. Here's the list of bootstrappers:
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, ];
You can find more information on how exceptions are handled in Laravel by checking this dive.
sendRequestThroughRouter() method called from
handle() has the following code:
return (new Pipeline($this->app)) ->send($request) ->through($this->app->shouldSkipMiddleware() ?  : $this->middleware) ->then($this->dispatchToRouter());
This translates to the following:
The router will find the suitable route that matches the request, collects the list of middleware assigned to this route and sends the request through them, run the code in your route definition, and finally prepares the response for display.
Terminating The Kernel
Once the response is ready, it's sent to the client via
$response->send(), after that the
Http\Kernel does some housekeeping before it terminates. This house keeping includes running Terminable Middleware and any termination callbacks registered in the container.
If you have any questions or find parts that need more clarification, please let me know. I'm going to update the post with more information based on the feedback I receive.