深入研究 Laravel 源码第四天
前言 单纯学习
分析 index.php http内核,将传入的请求发送到http内核或控制台内核,得到返回,终止请求
1、make(解析http控制台实例)
2、handle(处理请求)
3、Illuminate\Http\Request::capture()
4、send
5、terminate
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
//解析这个抽象的实例,在bootstrap/app.php中有注册单例App\Http\Kernel
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()//得到全局表单请求实例
);处理请求得到响应
$response->send();//发送响应
$kernel->terminate($request, $response)//终止请求
分析App\Http\Kernel 文件
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
忽略
}
分析Illuminate\Foundation\Http\Kernel
1. 引入
use Exception;//异常
use Throwable;//异常与错误
use Illuminate\Routing\Router;//路由类
use Illuminate\Routing\Pipeline;//路由管道类
use Illuminate\Support\Facades\Facade;//门面抽象类
use Illuminate\Contracts\Debug\ExceptionHandler;//异常处理程序
use Illuminate\Contracts\Foundation\Application;//基础应用接口
use Illuminate\Contracts\Http\Kernel as KernelContract;//基础http内核接口
use Symfony\Component\Debug\Exception\FatalThrowableError;
2. 成员变量
class Kernel implements KernelContract
{
//应用实例
protected $app
//路由实例
protected $router;
// 应用程序的引导类
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,
];
//中间件数组
protected $middleware = [];
//中间件组数组
protected $middlewareGroups = [];
//路由中间件
protected $routeMiddleware = [];
//*按优先级排序的中间件列表
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Auth\Middleware\Authenticate::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
3 . 构造函数
public function __construct(Application $app, Router $router)//依赖注入
{
$this->app = $app;
$this->router = $router;
$router->middlewarePriority = $this->middlewarePriority;//按优先级排序的中间件列表
foreach ($this->middlewareGroups as $key => $middleware) {
$router->middlewareGroup($key, $middleware);//添加路由中间件组
}
foreach ($this->routeMiddleware as $key => $middleware) {
$router->aliasMiddleware($key, $middleware);//添加中间件别名
}
}
4. 处理传入的HTTP请求
public function handle($request)
{
try {
//启用_method请求参数的支持,以确定预期的HTTP方法
$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;
}
5. 通过中间件/路由器发送给定的请求
1、bootstrap
2、Facade::clearResolvedInstance
3、send(设置通过管道发送的对象)
4、through(设置管道数组)
5、then(运行管道)
6、shouldSkipMiddleware
7、dispatchToRouter(获取路由调度器回调)
protected function sendRequestThroughRouter($request)
{
$this->app->instance('request', $request);//注册请求实例到request
Facade::clearResolvedInstance('request');//清除已解析的门面实例
$this->bootstrap();//运行引导程序
return (new Pipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());//中间件中的$next参数
}
6. 为HTTP请求引导应用程序
1、hasBeenBootstrapped
2、bootstrapWith
3、bootstrappers
public function bootstrap()
{
//判断程序是否自举
if (! $this->app->hasBeenBootstrapped()) {
$this->app->bootstrapWith($this->bootstrappers());//运行给定的引导类数组
}
}
7. 返回路由调度器回调(中间件中的$next参数)
protected function dispatchToRouter()
{
return function ($request) {
$this->app->instance('request', $request);
return $this->router->dispatch($request);
};
}
8. 终止内核
1、terminateMiddleware
2、 $this->app->terminate()
public function terminate($request, $response)
{
$this->terminateMiddleware($request, $response);//终止中间件
$this->app->terminate();//终止应用
}
9. 终止中间件
1、shouldSkipMiddleware
2、gatherRouteMiddleware
3、parseMiddleware
4、make
protected function terminateMiddleware($request, $response)
{
//获取所有中间件
$middlewares = $this->app->shouldSkipMiddleware() ? [] : array_merge(
$this->gatherRouteMiddleware($request),//获取当前请求的类的中间件
$this->middleware//全局公共中间件
);
foreach ($middlewares as $middleware) {
if (! is_string($middleware)) {
continue;
}
[$name] = $this->parseMiddleware($middleware);
$instance = $this->app->make($name);//解析中间件实例
if (method_exists($instance, 'terminate')) {
$instance->terminate($request, $response);//执行中间件终止方法
}
}
}
10. gatherRouteMiddleware
protected function gatherRouteMiddleware($request)
{
if ($route = $request->route()) {
return $this->router->gatherRouteMiddleware($route);//使用解析的类名收集给定路由的中间件
}
return [];
}
11. 解析中间件
protected function parseMiddleware($middleware)
{
[$name, $parameters] = array_pad(explode(':', $middleware, 2), 2, []);
if (is_string($parameters)) {
$parameters = explode(',', $parameters);
}
return [$name, $parameters];
}
12. hasMiddleware(是否存在全局中间件)
public function hasMiddleware($middleware)
{
return in_array($middleware, $this->middleware);
}
13. 插入新中间件到数组头部
public function prependMiddleware($middleware)
{
if (array_search($middleware, $this->middleware) === false) {
array_unshift($this->middleware, $middleware);
}
return $this;
}
14. 插入新中间件到数组尾部
public function pushMiddleware($middleware)
{
if (array_search($middleware, $this->middleware) === false) {
$this->middleware[] = $middleware;
}
return $this;
}
15. bootstrappers(获得应用引导程序)
protected function bootstrappers()
{
return $this->bootstrappers;
}
16. 向异常处理程序报告异常
protected function reportException(Exception $e)
{
$this->app[ExceptionHandler::class]->report($e);
}
17. 将异常输出到响应
protected function renderException($request, Exception $e)
{
return $this->app[ExceptionHandler::class]->render($request, $e);
}
18. getMiddlewareGroups
public function getMiddlewareGroups()
{
return $this->middlewareGroups;
}
19. getApplication
public function getApplication()
{
return $this->app;
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
laravel