diff options
| author | Sam Light <sam@lightscale.co.uk> | 2026-06-10 19:00:32 +0100 |
|---|---|---|
| committer | Sam Light <sam@lightscale.co.uk> | 2026-06-10 19:00:32 +0100 |
| commit | 5fe7c87967ff29c4a8f03a9186918d8359f4887e (patch) | |
| tree | dfdd4fdc7a4e96266305f82f5846750ab2efabc9 /src/Router.php | |
| parent | 01eac9658c3bc486d2d42a18557fdb82a536348e (diff) | |
big update
Diffstat (limited to 'src/Router.php')
| -rw-r--r-- | src/Router.php | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/Router.php b/src/Router.php index efcccfa..f666fe5 100644 --- a/src/Router.php +++ b/src/Router.php @@ -4,6 +4,77 @@ declare(strict_types=1); namespace Lightscale\Router; +use Lightscale\Router\Enums\HttpMethod; +use Lightscale\Router\Enums\PathSegmentType; +use Lightscale\Router\Exceptions\NotFoundException; +use Lightscale\Router\Exceptions\UnknownMethodException; +use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; + class Router { + private PathSegment $root; + + public function __construct() + { + $this->root = new PathSegment(type: PathSegmentType::Root); + } + + public function root(): PathSegment + { + return $this->root; + } + + /** @return string[] */ + private function splitPath(string $path): array + { + $split = explode('/', rtrim($path, '/')); + array_shift($split); + + return $split; + } + + public function findSegment(string $path): ?PathSegmentMatch + { + $pathSplit = $this->splitPath($path); + $seg = $this->root(); + $params = []; + + while (($v = array_shift($pathSplit)) !== null && null !== $seg) { + $seg = $seg->findChild($v); + + if (PathSegmentType::Parameter === $seg?->getType()) { + $params[$seg->getValue() ?? ''] = $v; + } + } + + return null === $seg ? null : new PathSegmentMatch( + segment: $seg, + parameters: $params + ); + } + + public function dispatch(RequestInterface $request): ResponseInterface + { + $uri = $request->getUri(); + $match = $this->findSegment($uri->getPath()); + + if (null === $match) { + throw new NotFoundException(); + } + + $segment = $match->segment; + $method = $request->getMethod(); + $method = ( + HttpMethod::tryFrom(strtolower($method)) ?? + throw new UnknownMethodException() + ); + $route = $segment->getRoute($method); + + if (null === $route) { + throw new NotFoundException(); + } + + return $route($request); + } } |
