middlewareChain = $this->createExecutionChain($middleware); } /** * Executes the given command and optionally returns a value * * @param object $command * * @return mixed */ public function handle($command) { if (!is_object($command)) { throw InvalidCommandException::forUnknownValue($command); } $middlewareChain = $this->middlewareChain; return $middlewareChain($command); } /** * @param Middleware[] $middlewareList * * @return callable */ private function createExecutionChain($middlewareList) { $lastCallable = function () { // the final callable is a no-op }; while ($middleware = array_pop($middlewareList)) { if (! $middleware instanceof Middleware) { throw InvalidMiddlewareException::forMiddleware($middleware); } $lastCallable = function ($command) use ($middleware, $lastCallable) { return $middleware->execute($command, $lastCallable); }; } return $lastCallable; } }