Files
D1041231092-webgis-povertymap/core/Router.php
T
2026-06-11 12:30:23 +07:00

64 lines
2.2 KiB
PHP

<?php
// core/Router.php
class Router {
private array $routes = [];
public function get(string $path, callable|array $handler): void {
$this->routes['GET'][$path] = $handler;
}
public function post(string $path, callable|array $handler): void {
$this->routes['POST'][$path] = $handler;
}
public function dispatch(): void {
$method = $_SERVER['REQUEST_METHOD'];
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
// Strip base path
$basePath = parse_url(APP_URL, PHP_URL_PATH);
if ($basePath && str_starts_with($uri, $basePath)) {
$uri = substr($uri, strlen($basePath));
}
$uri = '/' . ltrim($uri, '/');
if ($uri !== '/' && str_ends_with($uri, '/')) {
$uri = rtrim($uri, '/');
}
$routes = $this->routes[$method] ?? [];
// Two-pass: static routes (no {param}) matched first, dynamic routes second.
// This ensures /verifikator/warga/tambah is never swallowed by /verifikator/warga/{id}.
$staticRoutes = array_filter($routes, fn($p) => !str_contains($p, '{'), ARRAY_FILTER_USE_KEY);
$dynamicRoutes = array_filter($routes, fn($p) => str_contains($p, '{'), ARRAY_FILTER_USE_KEY);
foreach ([$staticRoutes, $dynamicRoutes] as $group) {
foreach ($group as $pattern => $handler) {
$regex = $this->buildRegex($pattern);
if (preg_match($regex, $uri, $matches)) {
array_shift($matches);
$params = array_values($matches);
if (is_array($handler)) {
[$controllerName, $action] = $handler;
$controller = new $controllerName();
$controller->$action(...$params);
} else {
$handler(...$params);
}
return;
}
}
}
// 404
http_response_code(404);
require APP_ROOT . '/app/views/public/404.php';
}
private function buildRegex(string $pattern): string {
$pattern = preg_replace('/\{(\w+)\}/', '([^/]+)', $pattern);
return '#^' . $pattern . '$#';
}
}