useful-api.org/router/Router.php

78 lines
1.9 KiB
PHP
Raw Normal View History

2023-11-22 20:25:33 +00:00
<?php
2023-11-23 22:45:49 +00:00
require_once(ROOT . "/utils/arrays.php");
2023-11-24 09:01:17 +00:00
require_once(ROOT . "/utils/error.php");
2023-11-23 22:45:49 +00:00
2023-11-22 20:25:33 +00:00
const GET = "GET";
const POST = "POST";
const PUT = "PUT";
const DELETE = "DELETE";
const HEAD = "HEAD";
const CONNECT = "CONNECT";
const OPTIONS = "OPTIONS";
const TRACE = "TRACE";
const PATCH = "PATCH";
class Router {
private $routes = [];
private $prefix = "";
2023-11-22 20:25:33 +00:00
public $notFoundHandler;
function __construct(string $prefix = "") {
$this->notFoundHandler = function(array &$context) {
2023-11-24 09:01:17 +00:00
setStatusCode(404);
2023-11-22 20:25:33 +00:00
require(ROOT . "/templates/404.php");
};
$this->prefix = $prefix;
2023-11-22 20:25:33 +00:00
}
private function findRoute(string $method, string $url) {
if (!key_exists($method, $this->routes)) {
return null;
}
$paths = $this->routes[$method];
foreach ($paths as $path => $handler) {
if (preg_match("/^" . str_replace("/", "\/", $path, ) . "$/", $url)) {
return $handler;
}
}
return null;
}
private function getPath($uri) {
if (($i = strpos($uri, "?")) !== false) {
return substr($uri, 0, $i);
} else {
return $uri;
}
}
public function addRoute(string $method, string $path, $handler) {
array_get_or_add($method, $this->routes, [])[$path] = $handler;
}
public function execute(array &$context = []) {
2023-11-22 20:25:33 +00:00
$path = $this->getPath($_SERVER["REQUEST_URI"]);
$path = substr($path, strlen($this->prefix));
2023-11-22 20:25:33 +00:00
$route = $this->findRoute($_SERVER["REQUEST_METHOD"], $path);
if (!$route) {
$route = $this->notFoundHandler;
}
$context["REQUEST_PATH"] = $path;
return $route($context);
}
2023-11-22 20:25:33 +00:00
// calling magic to make the router a handler and thus cascade-able
public function __invoke(array &$context = []) {
return $this->execute($context);
2023-11-22 20:25:33 +00:00
}
}
return new Router();