最初,一次请求将会到达public/index.php,这个文件的内容非常简单:
require __DIR__.'/../bootstrap/autoload.php';
$app = require_once __DIR__.'/../bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();
$kernel->terminate($request, $response);
define('LARAVEL_START', microtime(true));
require __DIR__.'/../vendor/autoload.php';
$compiledPath = __DIR__.'/cache/compiled.php';
if (file_exists($compiledPath)) {
require $compiledPath;
}
/vendor/autoload.php文件是composer提供的一个加载文件,引入这个文件之后我们就可以方便的使用其他类了。
之后是/cache/compile.php文件,包含了常用的类,以提升处理请求的性能。
再来看bootstrap/app.php:
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
return $app;
之后index.php创建了一个Kernel实例,打开Illuminate\Contracts\Http\Kernel::class,代码如下:
class Kernel extends HttpKernel
{
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
];
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
],
'api' => [
'throttle:60,1',
],
];
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
}
EncryptCookies::class用于处理对于cookies的加密解密;
AddQueuedCookiesToResponse::class用于给Response的header添加cookies信息;
StartSession::class用于首次请求时创建session信息,处理请求时验证session的有效性,在请求结束时保存session信息;
ShareErrorsFromSession::class返回session的错误信息;
VerifyCsrfToken::class验证CSRF令牌;
路由中间件:
Illuminate\Support\Facades\Auth\Authenticate::class用于验证发出的请求类型;
Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class用基本的Auth进行验证;
Illuminate\Foundation\Http\Middleware\Authorize::class将请求与模型绑定;
App\Http\Middleware\RedirectIfAuthenticated::class验证后重定向;
Illuminate\Routing\Middleware\ThrottleRequests::class用于请求频率的限制。
然后是对请求的捕捉,捕捉之后交给kernel::handle():
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']->fire('kernel.handled', [$request, $response]);
return $response;
}
首先是接收参数,然后通过路由转发请求。
public function terminate($request, $response)
{
$middlewares = $this->app->shouldSkipMiddleware() ? [] : array_merge(
$this->gatherRouteMiddlewares($request),
$this->middleware
);
foreach ($middlewares as $middleware) {
list($name, $parameters) = $this->parseMiddleware($middleware);
$instance = $this->app->make($name);
if (method_exists($instance, 'terminate')) {
$instance->terminate($request, $response);
}
}
$this->app->terminate();
}
通过kernel::gatherRouteMiddlewares()获取获取所有路由,并且对应要使用的中间件,然后对所有的中间件进行解析并进行处理,执行完之后终结请求。