_uri = $uri; $route = Route::resolve($uri); $this->_controller = $route['controller']; $this->_action = $route['action']; $this->_params = $route['params']; } public static function factory(): static { $uri = self::detect_uri(); $instance = new static($uri); if (self::$initial === null) { self::$initial = $instance; } self::$current = $instance; $instance->method($_SERVER['REQUEST_METHOD'] ?? HTTPRequest::GET); $instance->query($_GET); $instance->post($_POST); $instance->_requested_with = strtolower($_SERVER['HTTP_X_REQUESTED_WITH'] ?? ''); if ($instance->method() !== HTTPRequest::GET) { $body = file_get_contents('php://input'); if ($body !== false && $body !== '') { $instance->body($body); } } return $instance; } public static function detect_uri(): string { if (!empty($_SERVER['PATH_INFO'])) { $uri = $_SERVER['PATH_INFO']; } elseif (isset($_SERVER['REQUEST_URI'])) { $uri = $_SERVER['REQUEST_URI']; if ($path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)) { $uri = $path; } $uri = rawurldecode($uri); } elseif (isset($_SERVER['PHP_SELF'])) { $uri = $_SERVER['PHP_SELF']; } else { $uri = '/'; } return trim($uri, '/'); } public function execute(): Response { $method = lcfirst($this->_action) . 'Action'; $parts = explode('/', $this->_controller); $file = DOCROOT . '/App/Controller/' . implode('/', array_map('ucfirst', $parts)) . 'Controller.php'; if (!file_exists($file)) { return HTTPException::factory(404)->get_response(); } require_once $file; $class = 'App\\Controller\\' . implode('\\', array_map('ucfirst', $parts)) . 'Controller'; if (!method_exists($class, $method)) { return HTTPException::factory(404)->get_response(); } return (new Response())->body((new $class())->$method()); } public function method(?string $method = null): string|static { if ($method === null) { return $this->_method; } $this->_method = strtoupper($method); return $this; } public function post(null|string|array $key = null, mixed $value = null): null|array|string|static { if (is_array($key)) { $this->_post = $key; return $this; } if ($key === null) { return $this->_post; } if ($value === null) { return $this->_post[$key] ?? null; } $this->_post[$key] = $value; return $this; } public function query(null|string|array $key = null, mixed $value = null): null|array|string|static { if (is_array($key)) { $this->_get = $key; return $this; } if ($key === null) { return $this->_get; } if ($value === null) { return $this->_get[$key] ?? null; } $this->_get[$key] = $value; return $this; } public function body(?string $content = null): string|static { if ($content === null) { return $this->_body ?? ''; } $this->_body = $content; return $this; } public function requested_with(?string $value = null): string|static { if ($value === null) { return $this->_requested_with; } $this->_requested_with = strtolower($value); return $this; } public function is_ajax(): bool { return $this->_requested_with === 'xmlhttprequest'; } public function controller(): string { return $this->_controller; } public function action(): string { return $this->_action; } public function params(): array { return $this->_params; } public function uri(): string { return $this->_uri; } public function param(int $index, mixed $default = null): mixed { return $this->_params[$index] ?? $default; } }