url = trim($url, '/'); } public function setBasePath(string $basePath) { $this->basePath = $basePath; } public function get(string $path, callable $callable): self { return $this->addRoute(['GET'], $path, $callable); } public function post(string $path, callable $callable): self { return $this->addRoute(['GET'], $path, $callable); } public function match(string $path, callable $callable): self { return $this->addRoute(['GET', 'POST'], $path, $callable); } private function addRoute(array $methods, string $path, $callable): self { $route = new Route($path, $callable); foreach ($methods as $method) { $this->routes[$method][] = $route; } return $this; } public function url(string $url): string { if ($this->basePath !== '') { return "/" . $this->basePath . '/' . $url; } else { return $this->basePath . '/' . $url; } } public function run(DI $di): HttpResponse { if (!isset($this->routes[$_SERVER['REQUEST_METHOD']])) { throw new RouteNotFoundException('Unknown HTTP method'); } $url = $this->url; if ($this->basePath !== '') { if (PathHelper::startsWith($url, $this->basePath)) { $url = trim(substr($url, strlen($this->basePath)), '/'); } else { throw new RouteNotFoundException('No matching routes'); } } foreach ($this->routes[$_SERVER['REQUEST_METHOD']] as $route) { if ($route->matches($url)) { return $route->call($di); } } throw new RouteNotFoundException('No matching routes'); } }