在ootstrapapp.php文件中:
$app->singleton( IlluminateContractsHttpKernel::class, AppHttpKernel::class ); $app->singleton( IlluminateContractsConsoleKernel::class, AppConsoleKernel::class ); $app->singleton( IlluminateContractsDebugExceptionHandler::class, AppExceptionsHandler::class );
AppHttpKernel::class(中间件)
protected $middleware = [ IlluminateFoundationHttpMiddlewareCheckForMaintenanceMode::class, IlluminateFoundationHttpMiddlewareValidatePostSize::class, AppHttpMiddlewareTrimStrings::class, IlluminateFoundationHttpMiddlewareConvertEmptyStringsToNull::class, AppHttpMiddlewareTrustProxies::class, ];
vendorlaravelframeworksrcIlluminateFoundationHttpKernel.php
protected function sendRequestThroughRouter($request) { $this->app->instance('request', $request); Facade::clearResolvedInstance('request'); //针对请求为应用程序'拔靴带' 执行bootstrap类的数组 //在请求处理阶段共有7个环节,每一个环节由一个类来实现的 //而且每个类都会有一个bootstrap()函数用于实现准备工作 $this->bootstrap(); return (new Pipeline($this->app)) ->send($request) ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware) ->then($this->dispatchToRouter()); }
/** * Get the route dispatcher callback. *设置路由分发回调函数 * @return Closure */ protected function dispatchToRouter() { return function ($request) { $this->app->instance('request', $request); return $this->router->dispatch($request); }; }
vendorlaravelframeworksrcIlluminatePipelinePipeline.php
/** * Set the object being sent through the pipeline. *设置被送入管道的对象 * @param mixed $passable * @return $this */ public function send($passable) { $this->passable = $passable; return $this; }
/** * Set the array of pipes. *设置导管数组 * @param array|mixed $pipes * @return $this */ public function through($pipes) { $this->pipes = is_array($pipes) ? $pipes : func_get_args(); return $this; }
/** * 以一个回调函数为终点执行管道处理 */ public function then(Closure $destination) { $pipeline = array_reduce( array_reverse($this->pipes), $this->carry(), $this->prepareDestination($destination) ); return $pipeline($this->passable); }
/** * 获取一个用来代替洋葱层的回调函数 * * @return Closure */ protected function carry() { return function ($stack, $pipe) { return function ($passable) use ($stack, $pipe) { if (is_callable($pipe)) { return $pipe($passable, $stack); } elseif (! is_object($pipe)) { list($name, $parameters) = $this->parsePipeString($pipe); $pipe = $this->getContainer()->make($name); $parameters = array_merge([$passable, $stack], $parameters); } else { $parameters = [$passable, $stack]; } return method_exists($pipe, $this->method) ? $pipe->{$this->method}(...$parameters) : $pipe(...$parameters); }; }; }
在 Laravel 框架中,很多注释和代码名称已经非常形象地表达了程序代码的功能,代码注释中将中间件称为“洋葱”层,将整个处理流程称为“管道”,有些地方会用到这些名词,如果读者理解了真正的含义就会更容易理解程序。对清求的处理阶段, l1 ’先对管道类( Pipelinc 类)进行了实例化,分别通过 send ( )函数和 through ( )函数将请求实例和中间件数组赋值给管道实例,而鼓终的处理是通过 theno 函数完成的,该函数有一个参数,这个参数是经过“管道”后的终点处理函数,即下~步的路由处理。而 theno 函数其实就是将整个中间件数组通过服务容器’仁成实例,并对这些实例的 handlco 函数和传入的终点处理 l " l 调函数进行组装,形成一个递归调用的回调函数,再进行调用,最终完成“管道”的逐级处理