middlewareLock) { throw new RuntimeException('Middleware can’t be added once the stack is dequeuing'); } if (is_null($this->tip)) { $this->seedMiddlewareStack(); } $next = $this->tip; $this->tip = function ( ServerRequestInterface $request, ResponseInterface $response ) use ( $callable, $next ) { $result = call_user_func($callable, $request, $response, $next); if ($result instanceof ResponseInterface === false) { throw new UnexpectedValueException( 'Middleware must return instance of \Psr\Http\Message\ResponseInterface' ); } return $result; }; return $this; } /** * Seed middleware stack with first callable * * @param callable $kernel The last item to run as middleware * * @throws RuntimeException if the stack is seeded more than once */ protected function seedMiddlewareStack(callable $kernel = null) { if (!is_null($this->tip)) { throw new RuntimeException('MiddlewareStack can only be seeded once.'); } if ($kernel === null) { $kernel = $this; } $this->tip = $kernel; } /** * Call middleware stack * * @param ServerRequestInterface $request A request object * @param ResponseInterface $response A response object * * @return ResponseInterface */ public function callMiddlewareStack(ServerRequestInterface $request, ResponseInterface $response) { if (is_null($this->tip)) { $this->seedMiddlewareStack(); } /** @var callable $start */ $start = $this->tip; $this->middlewareLock = true; $response = $start($request, $response); $this->middlewareLock = false; return $response; } }