Laravel5.5解析-Pipeline()获取$response

Pipeline()返回$response

回顾:完成bootstrap()后终于要获取$response了

	//Illuminate\Foundation\Http\Kernel
    public function handle($request)
    {
        $request->enableHttpMethodParameterOverride();
        
        $response = $this->sendRequestThroughRouter($request);
        
        $this->app['events']->dispatch(
            new Events\RequestHandled($request, $response)
        );

        return $response;
    }

    protected function sendRequestThroughRouter($request)
    {
        $this->app->instance('request', $request);

        Facade::clearResolvedInstance('request');

        $this->bootstrap();

        return (new Pipeline($this->app))
                    ->send($request)
                    ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                    ->then($this->dispatchToRouter());
    }

Pipeline

namespace Illuminate\Routing;

use Illuminate\Pipeline\Pipeline as BasePipeline;
class Pipeline extends BasePipeline
{
	protected function carry()
    {
        return function ($stack, $pipe) {
            return function ($passable) use ($stack, $pipe) {
                    $slice = parent::carry();
                    $callable = $slice($stack, $pipe);
                    return $callable($passable);
            };
        };
    }
}
namespace Illuminate\Pipeline;

use Illuminate\Contracts\Pipeline\Pipeline as PipelineContract;
class Pipeline implements PipelineContract
{
    protected $container;
    protected $passable;
    protected $pipes = [];
    protected $method = 'handle';
    
    public function __construct(Container $container = null)
    {
        $this->container = $container;
    }
    
    public function send($passable)
    {
        $this->passable = $passable;

        return $this;
    }

    public function through($pipes)
    {
        $this->pipes = is_array($pipes) ? $pipes : func_get_args();

        return $this;
    }

    public function then(Closure $destination)
    {
        $pipeline = array_reduc
            array_reverse($this->pipes), $this->carry(), $this->prepareDestination($destination)
        );
        
        return $pipeline($this->passable);
    }
}

动作解析

			(new Pipeline($this->app))//container属性引用服务容器
                    ->send($request)//passable引用$request实例
                    ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)//pipes赋值中间件
                    ->then($this->dispatchToRouter());//核心动作,将中间件类名以use关键字存储在匿名函数中,递归执行

then()

    public function then(Closure $destination)
    {
        $pipeline = array_reduce(
            array_reverse($this->pipes), $this->carry(), $this->prepareDestination($destination)
        );
        
        return $pipeline($this->passable);
    }

$this->pipes:

array:5 [0 => "Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode"
  1 => "Illuminate\Foundation\Http\Middleware\ValidatePostSize"
  2 => "App\Http\Middleware\TrimStrings"
  3 => "Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull"
  4 => "App\Http\Middleware\TrustProxies"
]

array_reverse($this->pipes):将数组反转,因为$pipeline匿名函数对中间件对存储是先今后出
$this->carry()返回匿名函数

	//class Illuminate\Routing\Pipeline
	
	function ($stack, $pipe) {
            return function ($passable) use ($stack, $pipe) {
                    $slice = parent::carry();
                    $callable = $slice($stack, $pipe);
                    return $callable($passable);
            };
        };

$this->prepareDestination($destination)返回

	function ($request) {
            $this->app->instance('request', $request);
            return $this->router->dispatch($request);
        };

array_reduce ( array $array , callable $callback [, mixed $initial = NULL ] )
这个函数将数组的值遍历通过回调函数处理,最终返回一个值
callback ( mixed $carry , mixed $item ) : mixed
$carry:之前迭代的值
$item:本次迭代的值
回到then()

	//class Illuminate\Pipeline\Pipeline;
    public function then(Closure $destination)
    {
    	//carry()才是动作的核心,当前执行的是Illuminate\Routing\Pipeline carry()
        $pipeline = array_reduce(
            array_reverse($this->pipes), $this->carry(), $this->prepareDestination($destination)
        );
        
        return $pipeline($this->passable);
    }
	//class Illuminate\Routing\Pipeline
	function ($stack, $pipe) {
            return function ($passable) use ($stack, $pipe) {
                    $slice = parent::carry();
                    $callable = $slice($stack, $pipe);
                    return $callable($passable);
            };
        };
	//class Illuminate\Pipeline\Pipeline;
    protected function carry()
    {
        return function ($stack, $pipe) {
            return function ($passable) use ($stack, $pipe) {
                    list($name, $parameters) = $this->parsePipeString($pipe);
                    $pipe = $this->getContainer()->make($name);
                    $parameters = array_merge([$passable, $stack], $parameters);
                return method_exists($pipe, $this->method)
                                ? $pipe->{$this->method}(...$parameters)
                                : $pipe(...$parameters);
            };
        };
    }

这里在处理数组的过程中,最初$stack 为dispatchToRouter()返回的匿名函数,$pipe为当前指针下数组的值,依次更新指针,依次返回匿名函数,每次匿名函数的关键在与use ($stack,$pipe),这里存储的是指针上一个位置返回的匿名函数和当前数组指针的值,其核心动作也是在档次执行的过程中使用$pipe参数执行当前动作,执行完毕后在执行$stack($parameters)最后执行dispatchToRouter();
Closure {#134 ▼
class: “Illuminate\Routing\Pipeline”
this: Pipeline {#30 …}
parameters: {▶}
use: {▶}
file: “/usr/local/var/www/auth/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php”
line: “49 to 61”
}
“Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull”
Closure {#131 ▼
class: “Illuminate\Routing\Pipeline”
this: Pipeline {#30 …}
parameters: {▶}
use: {▼
$stack: Closure {#134 …}
$pipe: “Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull”
}
file: “/usr/local/var/www/auth/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php”
line: “49 to 61”
}
“App\Http\Middleware\TrimStrings”
Closure {#133 ▼
class: “Illuminate\Routing\Pipeline”
this: Pipeline {#30 …}
parameters: {▶}
use: {▼
$stack: Closure {#131 …}.
$pipe: “App\Http\Middleware\TrimStrings”
}
file: “/usr/local/var/www/auth/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php”
line: “49 to 61”
}

#133 : use $stack -> #131:use $stack -> #134…
这就是其执行过程了;我们看回调函数的执行吧!

    public function then(Closure $destination)
    {
        $pipeline = array_reduce(
            array_reverse($this->pipes), $this->carry(), $this->prepareDestination($destination)
        );
        //there ...
        return $pipeline($this->passable);
    }

$this->passable是$request实例,执行最终返回的匿名函数,将$request作为参数传递。

	//class Illuminate\Routing\Pipeline
	function ($stack, $pipe) {
            return function ($passable) use ($stack, $pipe) {
                    $slice = parent::carry();//执行父类,返回匿名函数
                    $callable = $slice($stack, $pipe);//执行父类返回的匿名函数,再次返回匿名函数
                    return $callable($passable);//执行匿名函数
            };
        };
	//class Illuminate\Pipeline\Pipeline;
    protected function carry()
    {
        return function ($stack, $pipe) {
            return function ($passable) use ($stack, $pipe) {
                    list($name, $parameters) = $this->parsePipeString($pipe);
                    $pipe = $this->getContainer()->make($name);//使用服务容器创建目标实例
                    $parameters = array_merge([$passable, $stack], $parameters);
                    //执行$pipe->handle();
                return method_exists($pipe, $this->method)
                                ? $pipe->{$this->method}(...$parameters)
                                : $pipe(...$parameters);
            };
        };
    }
    //handle()返回传递的匿名参数的执行结果,实现的效果类似递归执行匿名函数
    public function handle($request, Closure $next)
    {
		...

        return $next($request);
    }

最终执行dispatchToRouter(),在这里才真正实现的路由解析的动作,不过,最近有点忙,就先到这里吧!等找到工作了空余时间我再更新路由解析的过程!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值