method = $_SERVER['REQUEST_METHOD']; // Normalize path: extract /api/v1/... portion from any subdirectory structure $rawPath = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); $apiPos = strpos($rawPath, '/api/v1/'); if ($apiPos !== false) { $this->path = substr($rawPath, $apiPos); // e.g. /api/v1/auth/login } else { $this->path = $rawPath; } $this->headers = getallheaders(); $this->queryParams = $_GET; $this->files = $_FILES; $contentType = $this->getHeader('Content-Type'); if ($contentType && str_contains($contentType, 'application/json')) { $this->body = json_decode(file_get_contents('php://input'), true) ?? []; } else { $this->body = $_POST; } } public function getMethod(): string { return $this->method; } public function getPath(): string { return $this->path; } public function getHeaders(): array { return $this->headers; } public function getQueryParams(): array { return $this->queryParams; } public function getBody(): array { return $this->body; } public function getFiles(): array { return $this->files; } public function getHeader(string $name): ?string { $name = strtolower($name); foreach ($this->headers as $key => $value) { if (strtolower($key) === $name) { return $value; } } return null; } public function input(string $key, mixed $default = null): mixed { return $this->body[$key] ?? $this->queryParams[$key] ?? $default; } }