uri = is_countable($_SERVER['REQUEST_URI']) && count($_SERVER['REQUEST_URI']) > 1 ? rtrim($_SERVER['REQUEST_URI'], "/") : $_SERVER['REQUEST_URI']; $this->uri = str_replace($pathname, "", $this->uri); $this->requestType = $_SERVER['REQUEST_METHOD']; $this->routes = []; $this->middleware = []; if (isset($_SERVER)) { $this->request = $_SERVER; } if (isset($_POST)) { $this->request["body"] = $_POST; } if (isset($_POST)) { $this->request["params"] = $_GET; } $this->response = new Response(); } /** * Use Middleware * @param string $uri * @param $middleware * @return void */ public function use(string $uri, callable $middleware): void { $this->middleware[$uri] = $middleware; } /** * get Middleware for uri * @param string $uri * @return array */ private function getMiddleware(): array { $middleware = []; foreach ($this->middleware as $key => $value) { if (str_starts_with($this->uri, $key)) { $middleware[] = $value; } } return $middleware; } /** * Calls the middleware * @param array $middleware * @return void */ private function callMiddleware(array $middleware): void { foreach ($middleware as $m) { $m($this->request, $this->response); } } /** * GET Method * @param string $uri * @param $controller * @return void */ public function get(string $uri, callable $controller): void { $this->routes[$uri] = new Route("GET", $controller); } /** * POST Method * @param string $uri * @param $controller * @return void */ public function post(string $uri, callable $controller): void { $this->routes[$uri] = new Route("POST", $controller); } /** * PUT Method * @param string $uri * @param $controller * @return void */ public function put(string $uri, callable $controller): void { $this->routes[$uri] = new Route("PUT", $controller); } /** * DELETE Method * @param string $uri * @param $controller * @return void */ public function delete(string $uri, callable $controller): void { $this->routes[$uri] = new Route("DELETE", $controller); } /** * ALL Method * @param string $uri * @param $controller * @return void */ public function all(string $uri, callable $controller): void { $this->routes[$uri] = new Route("ALL", $controller); } /** * Route * @param string $uri * @return void */ public function route(string $uri): Route { $this->routes[$uri] = new Route($uri); return $this->routes[$uri]; } /** * Checks if the given uri matches the given route * @param string $uri * @param array $params * @return string */ private function routeMatches(string $route, string $uri): bool { $routeParts = explode("/", $route); $uriParts = explode("/", $uri); if (count($routeParts) !== count($uriParts)) { return false; } foreach ($routeParts as $key => $part) { if (str_starts_with($part, ":")) { continue; } if ($part !== $uriParts[$key]) { return false; } } return true; } /** * Returns the params of the given uri * given that the uri matches the given route * @param string $uri * @param array $params * @return array */ private function getParams(string $route, string $uri): array { $routeParts = explode("/", $route); $uriParts = explode("/", $uri); $params = []; foreach ($routeParts as $key => $part) { if (str_starts_with($part, ":")) { $params[ltrim($part, ":")] = $uriParts[$key]; } } return $params; } /** * gets the controller for the given uri * @param array $routes */ private function getController(): callable|bool { foreach ($this->routes as $uri => $route) { if ($this->uri === $uri) { return $route->getController($this->requestType) ?? false; } if ($this->routeMatches($uri, $this->uri)) { $this->request["params"] = $this->getParams($uri, $this->uri); return $route->getController($this->requestType) ?? false; } } return false; } /** * Starts the router * @return void */ public function start(): void { $middleware = $this->getMiddleware(); $this->callMiddleware($middleware); $controller = $this->getController(); if ($controller) { $controller($this->request, $this->response); } else { echo "404"; } } }