Skip to content

Instantly share code, notes, and snippets.

@hiroy
Created May 22, 2019 13:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hiroy/162bdb0884967f12a494d2ca3c1c0e96 to your computer and use it in GitHub Desktop.
Save hiroy/162bdb0884967f12a494d2ca3c1c0e96 to your computer and use it in GitHub Desktop.
雑なHTTP Handler(Middleware、RequestHandler)のdispatcher
<?php
declare(strict_types=1);
namespace Kurumi;
use InvalidArgumentException;
use LogicException;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class Dispatcher implements MiddlewareInterface, RequestHandlerInterface
{
protected $container;
protected $httpHandlers;
protected $next;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->httpHandlers = [];
}
public function with($httpHandler): self
{
if (! is_array($httpHandler)) {
$httpHandler = [$httpHandler];
}
foreach ($httpHandler as $hh) {
$this->httpHandlers[] = $hh;
}
return $this;
}
public function dispatch(ServerRequestInterface $request): ResponseInterface
{
reset($this->httpHandlers);
return $this->handle($request);
}
public function handle(ServerRequestInterface $request): ResponseInterface
{
$httpHandler = $this->getEntry();
if ($httpHandler === false) {
if ($this->next !== null) {
return $this->next->handle($request);
}
throw new LogicException('HTTP handlers queue exhausted.');
}
if ($httpHandler instanceof MiddlewareInterface) {
return $httpHandler->process($request, $this);
} elseif ($httpHandler instanceof RequestHandlerInterface) {
return $httpHandler->handle($request);
}
}
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $next
): ResponseInterface {
$this->next = $next;
return $this->dispatch($request);
}
protected function getEntry()
{
$httpHandler = current($this->httpHandlers);
next($this->httpHandlers);
if ($httpHandler === false) {
return false;
}
if (is_string($httpHandler)) {
$httpHandler = $this->container->get($httpHandler);
}
if ($httpHandler instanceof MiddlewareInterface
|| $httpHandler instanceof RequestHandlerInterface) {
return $httpHandler;
}
throw new InvalidArgumentException('No valid HTTP handler provided.');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment