From 63f7ef5eeedc805ba3357c434d3caf5ec793a59d Mon Sep 17 00:00:00 2001 From: Johannes Kantz <67144859+JohannesKantz@users.noreply.github.com> Date: Thu, 8 Dec 2022 14:43:05 +0100 Subject: [PATCH] add: Router --- Router/Response.php | 44 +++++++++ Router/Route.php | 49 ++++++++++ Router/Router.php | 227 ++++++++++++++++++++++++++++++++++++++++++++ index.php | 15 +++ 4 files changed, 335 insertions(+) create mode 100644 Router/Response.php create mode 100644 Router/Route.php create mode 100644 Router/Router.php diff --git a/Router/Response.php b/Router/Response.php new file mode 100644 index 0000000..bfd335c --- /dev/null +++ b/Router/Response.php @@ -0,0 +1,44 @@ +methods[$method] = $controller; + } + } + + public function get($controller) + { + $this->methods["GET"] = $controller; + return $this; + } + + public function post($controller) + { + $this->methods["POST"] = $controller; + return $this; + } + + public function put($controller) + { + $this->methods["PUT"] = $controller; + return $this; + } + + public function delete($controller) + { + $this->methods["DELETE"] = $controller; + return $this; + } + + public function all($controller) + { + $this->methods["ALL"] = $controller; + return $this; + } + + public function getController(string $method) + { + return $this->methods[$method] ?? $this->methods["ALL"]; + } +} \ No newline at end of file diff --git a/Router/Router.php b/Router/Router.php new file mode 100644 index 0000000..936dd4f --- /dev/null +++ b/Router/Router.php @@ -0,0 +1,227 @@ +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"; + } + } +} \ No newline at end of file diff --git a/index.php b/index.php index b3d9bbc..9be39bc 100644 --- a/index.php +++ b/index.php @@ -1 +1,16 @@ get("/", function (array $req, Response $res) { + $res->send("Hello World"); +}); + +$app->start(); \ No newline at end of file