<?php
declare(strict_types=1); namespace App\Routing; use App\Exceptions\NotFoundException; class Router { private array $routes = []; public function add(string $method, string $path, callable $handler): void { $pattern = preg_replace('/\{([a-zA-Z0-9_]+)\}/', '(?<$1>[^/]+)', $path); $pattern = '#^' . $pattern . '$#'; $this->routes[] = [ 'method' => strtoupper($method), 'pattern' => $pattern, 'handler' => $handler ]; } public function get(string $path, callable $handler): void { $this->add('GET', $path, $handler); } public function post(string $path, callable $handler): void { $this->add('POST', $path, $handler); } public function put(string $path, callable $handler): void { $this->add('PUT', $path, $handler); } public function patch(string $path, callable $handler): void { $this->add('PATCH', $path, $handler); } public function delete(string $path, callable $handler): void { $this->add('DELETE', $path, $handler); } public function dispatch(string $method, string $uri) { $method = strtoupper($method); $path = parse_url($uri, PHP_URL_PATH) ?? '/'; foreach ($this->routes as $route) { if ($route['method'] === $method && preg_match($route['pattern'], $path, $matches)) { $params = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY); return call_user_func_array($route['handler'], array_values($params)); } } throw new NotFoundException('Route not found'); } } 