Laravel中中间件调用过程:Part 2 我看不懂......

来源:互联网 发布:淘宝网丝巾大全 编辑:程序博客网 时间:2024/06/09 06:32

接着上一篇来,上面结束中实例化了一个new Pipeline($this->app)类,跟该类有关的类有3个:

接口类

<?phpnamespace Illuminate\Contracts\Pipeline;use Closure;interface Pipeline{    /**     * Set the traveler object being sent on the pipeline.     *     * @param  mixed  $traveler     * @return $this     */    public function send($traveler);    /**     * Set the stops of the pipeline.     *     * @param  dynamic|array  $stops     * @return $this     */    public function through($stops);    /**     * Set the method to call on the stops.     *     * @param  string  $method     * @return $this     */    public function via($method);    /**     * Run the pipeline with a final destination callback.     *     * @param  \Closure  $destination     * @return mixed     */    public function then(Closure $destination);}

父类

<?phpnamespace Illuminate\Pipeline;use Closure;use RuntimeException;use Illuminate\Contracts\Container\Container;use Illuminate\Contracts\Pipeline\Pipeline as PipelineContract;class Pipeline implements PipelineContract{    /**     * The container implementation.     *     * @var \Illuminate\Contracts\Container\Container     */    protected $container;    /**     * The object being passed through the pipeline.     *     * @var mixed     */    protected $passable;    /**     * The array of class pipes.     *     * @var array     */    protected $pipes = [];    /**     * The method to call on each pipe.     *     * @var string     */    protected $method = 'handle';    /**     * Create a new class instance.     *     * @param  \Illuminate\Contracts\Container\Container|null  $container     * @return void     */    public function __construct(Container $container = null)    {        $this->container = $container;    }    /**     * 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;    }    /**     * Set the method to call on the pipes.     *     * @param  string  $method     * @return $this     */    public function via($method)    {        $this->method = $method;        return $this;    }    /**     * Run the pipeline with a final destination callback.     *     * @param  \Closure  $destination     * @return mixed     */    public function then(Closure $destination)    {        $pipeline = array_reduce(            array_reverse($this->pipes), $this->carry(), $this->prepareDestination($destination)        );        return $pipeline($this->passable);    }    /**     * Get the final piece of the Closure onion.     *     * @param  \Closure  $destination     * @return \Closure     */    protected function prepareDestination(Closure $destination)    {        return function ($passable) use ($destination) {            return $destination($passable);        };    }    /**     * Get a Closure that represents a slice of the application onion.     *     * @return \Closure     */    protected function carry()    {        return function ($stack, $pipe) {            return function ($passable) use ($stack, $pipe) {                if ($pipe instanceof Closure) {                    // If the pipe is an instance of a Closure, we will just call it directly but                    // otherwise we'll resolve the pipes out of the container and call it with                    // the appropriate method and arguments, returning the results back out.                    return $pipe($passable, $stack);                } elseif (! is_object($pipe)) {                    list($name, $parameters) = $this->parsePipeString($pipe);                    // If the pipe is a string we will parse the string and resolve the class out                    // of the dependency injection container. We can then build a callable and                    // execute the pipe function giving in the parameters that are required.                    $pipe = $this->getContainer()->make($name);                    $parameters = array_merge([$passable, $stack], $parameters);                } else {                    // If the pipe is already an object we'll just make a callable and pass it to                    // the pipe as-is. There is no need to do any extra parsing and formatting                    // since the object we're given was already a fully instantiated object.                    $parameters = [$passable, $stack];                }                return $pipe->{$this->method}(...$parameters);            };        };    }    /**     * Parse full pipe string to get name and parameters.     *     * @param  string $pipe     * @return array     */    protected function parsePipeString($pipe)    {        list($name, $parameters) = array_pad(explode(':', $pipe, 2), 2, []);        if (is_string($parameters)) {            $parameters = explode(',', $parameters);        }        return [$name, $parameters];    }    /**     * Get the container instance.     *     * @return \Illuminate\Contracts\Container\Container     * @throws \RuntimeException     */    protected function getContainer()    {        if (! $this->container) {            throw new RuntimeException('A container instance has not been passed to the Pipeline.');        }        return $this->container;    }}

调用类

<?phpnamespace Illuminate\Routing;use Closure;use Exception;use Throwable;use Illuminate\Http\Request;use Illuminate\Contracts\Debug\ExceptionHandler;use Illuminate\Pipeline\Pipeline as BasePipeline;use Symfony\Component\Debug\Exception\FatalThrowableError;/** * This extended pipeline catches any exceptions that occur during each slice. * * The exceptions are converted to HTTP responses for proper middleware handling. */class Pipeline extends BasePipeline{    /**     * Get the final piece of the Closure onion.     *     * @param  \Closure  $destination     * @return \Closure     */    protected function prepareDestination(Closure $destination)    {        return function ($passable) use ($destination) {            try {                return $destination($passable);            } catch (Exception $e) {                return $this->handleException($passable, $e);            } catch (Throwable $e) {                return $this->handleException($passable, new FatalThrowableError($e));            }        };    }    /**     * Get a Closure that represents a slice of the application onion.     *     * @return \Closure     */    protected function carry()    {        return function ($stack, $pipe) {            return function ($passable) use ($stack, $pipe) {                try {                    $slice = parent::carry();                    $callable = $slice($stack, $pipe);                    return $callable($passable);                } catch (Exception $e) {                    return $this->handleException($passable, $e);                } catch (Throwable $e) {                    return $this->handleException($passable, new FatalThrowableError($e));                }            };        };    }    /**     * Handle the given exception.     *     * @param  mixed  $passable     * @param  \Exception  $e     * @return mixed     *     * @throws \Exception     */    protected function handleException($passable, Exception $e)    {        if (! $this->container->bound(ExceptionHandler::class) || ! $passable instanceof Request) {            throw $e;        }        $handler = $this->container->make(ExceptionHandler::class);        $handler->report($e);        $response = $handler->render($passable, $e);        if (method_exists($response, 'withException')) {            $response->withException($e);        }        return $response;    }}

看不懂。。。。。。

原创粉丝点击