routesDir = $routesDir; $this->config = $config; } function registerStatusHandler(int $status, callable $handler) { $this->statusHandlers[$status] = $handler; } function setExceptionHandler(callable $handler) { $this->exceptionHandler = \Closure::fromCallable($handler); } private function dealWithError(int $status, string $path) { http_response_code($status); if (isset($this->statusHandlers[$status])) { $this->statusHandlers[$status]($path); } else { echo '

' . $status . ' for ' . htmlspecialchars($path) . '

'; } } private function dealWithException(\Throwable $e) { http_response_code(500); if (isset($this->exceptionHandler)) { ($this->exceptionHandler)($e); } else { echo '

Internal Server Error

'; } } function dispatch(string $path) { if (str_contains($path, '..')) { $this->dealWithError(404, $path); return; } if (file_exists($this->routesDir . $path . '.php')) { require_once $this->routesDir . $path . '.php'; } elseif (file_exists($this->routesDir . $path . 'index.php')) { require_once $this->routesDir . $path . 'index.php'; } else { $this->dealWithError(404, $path); return; } if (function_exists($_SERVER['REQUEST_METHOD'])) { try { $_SERVER['REQUEST_METHOD']($this->config); } catch (\Exception|\Error $e) { $this->dealWithException($e); } } else { $this->dealWithError(405, $path); } } }