在\bootstrap\app.php文件中:
$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
);
App\Http\Kernel::class(中间件)
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
];
\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.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);
};
}
\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.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 调函数进行组装,形成一个递归调用的回调函数,再进行调用,最终完成“管道”的逐级处理