* * For the full copyright and license information, please view * the LICENSE file that was distributed with this source code. */ namespace CodeIgniter; use CodeIgniter\Exceptions\InvalidArgumentException; /** * Superglobals manipulation. * * Provides a clean API for accessing and manipulating PHP superglobals * with support for testing and backward compatibility. * * Note on return types: * - $_SERVER can contain int (argc, REQUEST_TIME) or float (REQUEST_TIME_FLOAT) * - $_SERVER['argv'] is an array * - $_GET, $_POST, $_REQUEST can contain nested arrays from query params like ?foo[bar]=value * - $_COOKIE typically contains strings but can have arrays with cookie[key] notation * * Note: $_FILES only supports array operations (getFilesArray/setFilesArray). * Individual key operations are not provided as files don't change after request initialization. * * @phpstan-type server_items array|float|int|string * @phpstan-type get_items array|string * @phpstan-type post_items array|string * @phpstan-type cookie_items array|string * @phpstan-type files_items array * @phpstan-type request_items array|string * * @internal * @see \CodeIgniter\SuperglobalsTest */ final class Superglobals { /** * @var array */ private array $server = []; /** * @var array */ private array $get = []; /** * @var array */ private array $post = []; /** * @var array */ private array $cookie = []; /** * @var array */ private array $files = []; /** * @var array */ private array $request = []; /** * @param array|null $server * @param array|null $get * @param array|null $post * @param array|null $cookie * @param array|null $files * @param array|null $request */ public function __construct( ?array $server = null, ?array $get = null, ?array $post = null, ?array $cookie = null, ?array $files = null, ?array $request = null, ) { $this ->setServerArray($server ?? $_SERVER) ->setGetArray($get ?? $_GET) ->setPostArray($post ?? $_POST) ->setCookieArray($cookie ?? $_COOKIE) ->setFilesArray($files ?? $_FILES) ->setRequestArray($request ?? $_REQUEST); } /** * Get a value from $_SERVER. * * @param server_items|null $default * * @return server_items|null */ public function server(string $key, mixed $default = null): array|float|int|string|null { return $this->server[$key] ?? $default; } /** * Set a value in $_SERVER. * * @param server_items $value */ public function setServer(string $key, array|float|int|string $value): self { $this->server[$key] = $value; $_SERVER[$key] = $value; return $this; } /** * Remove a key from $_SERVER. */ public function unsetServer(string $key): self { unset($this->server[$key], $_SERVER[$key]); return $this; } /** * Get all $_SERVER values. * * @return array */ public function getServerArray(): array { return $this->server; } /** * Set the entire $_SERVER array. * * @param array $array */ public function setServerArray(array $array): self { $this->server = $array; $_SERVER = $array; return $this; } /** * Get a value from $_GET. * * @param get_items|null $default * * @return get_items|null */ public function get(string $key, mixed $default = null): array|string|null { return $this->get[$key] ?? $default; } /** * Set a value in $_GET. * * @param get_items $value */ public function setGet(string $key, array|string $value): self { $this->get[$key] = $value; $_GET[$key] = $value; return $this; } /** * Remove a key from $_GET. */ public function unsetGet(string $key): self { unset($this->get[$key], $_GET[$key]); return $this; } /** * Get all $_GET values. * * @return array */ public function getGetArray(): array { return $this->get; } /** * Set the entire $_GET array. * * @param array $array */ public function setGetArray(array $array): self { $this->get = $array; $_GET = $array; return $this; } /** * Get a value from $_POST. * * @param post_items|null $default * * @return post_items|null */ public function post(string $key, mixed $default = null): array|string|null { return $this->post[$key] ?? $default; } /** * Set a value in $_POST. * * @param post_items $value */ public function setPost(string $key, array|string $value): self { $this->post[$key] = $value; $_POST[$key] = $value; return $this; } /** * Remove a key from $_POST. */ public function unsetPost(string $key): self { unset($this->post[$key], $_POST[$key]); return $this; } /** * Get all $_POST values. * * @return array */ public function getPostArray(): array { return $this->post; } /** * Set the entire $_POST array. * * @param array $array */ public function setPostArray(array $array): self { $this->post = $array; $_POST = $array; return $this; } /** * Get a value from $_COOKIE. * * @param cookie_items|null $default * * @return cookie_items|null */ public function cookie(string $key, mixed $default = null): array|string|null { return $this->cookie[$key] ?? $default; } /** * Set a value in $_COOKIE. * * @param cookie_items $value */ public function setCookie(string $key, array|string $value): self { $this->cookie[$key] = $value; $_COOKIE[$key] = $value; return $this; } /** * Remove a key from $_COOKIE. */ public function unsetCookie(string $key): self { unset($this->cookie[$key], $_COOKIE[$key]); return $this; } /** * Get all $_COOKIE values. * * @return array */ public function getCookieArray(): array { return $this->cookie; } /** * Set the entire $_COOKIE array. * * @param array $array */ public function setCookieArray(array $array): self { $this->cookie = $array; $_COOKIE = $array; return $this; } /** * Get a value from $_REQUEST. * * @param request_items|null $default * * @return request_items|null */ public function request(string $key, mixed $default = null): array|string|null { return $this->request[$key] ?? $default; } /** * Set a value in $_REQUEST. * * @param request_items $value */ public function setRequest(string $key, array|string $value): self { $this->request[$key] = $value; $_REQUEST[$key] = $value; return $this; } /** * Remove a key from $_REQUEST. */ public function unsetRequest(string $key): self { unset($this->request[$key], $_REQUEST[$key]); return $this; } /** * Get all $_REQUEST values. * * @return array */ public function getRequestArray(): array { return $this->request; } /** * Set the entire $_REQUEST array. * * @param array $array */ public function setRequestArray(array $array): self { $this->request = $array; $_REQUEST = $array; return $this; } /** * Get all $_FILES values. * * @return array */ public function getFilesArray(): array { return $this->files; } /** * Set the entire $_FILES array. * * @param array $array */ public function setFilesArray(array $array): self { $this->files = $array; $_FILES = $array; return $this; } /** * Get a superglobal array by name. * * @param string $name The superglobal name (server, get, post, cookie, files, request) * * @return array * * @throws InvalidArgumentException If the superglobal name is invalid */ public function getGlobalArray(string $name): array { return match ($name) { 'server' => $this->server, 'get' => $this->get, 'post' => $this->post, 'cookie' => $this->cookie, 'files' => $this->files, 'request' => $this->request, default => throw new InvalidArgumentException( "Invalid superglobal name '{$name}'. Must be one of: server, get, post, cookie, files, request.", ), }; } /** * Set a superglobal array by name. * * @param string $name The superglobal name (server, get, post, cookie, files, request) * @param array $array The array to set * * @throws InvalidArgumentException If the superglobal name is invalid */ public function setGlobalArray(string $name, array $array): void { match ($name) { 'server' => $this->setServerArray($array), 'get' => $this->setGetArray($array), 'post' => $this->setPostArray($array), 'cookie' => $this->setCookieArray($array), 'files' => $this->setFilesArray($array), 'request' => $this->setRequestArray($array), default => throw new InvalidArgumentException( "Invalid superglobal name '{$name}'. Must be one of: server, get, post, cookie, files, request.", ), }; } }