diff --git a/system/HTTP/SiteURIFactory.php b/system/HTTP/SiteURIFactory.php index 73cc9fe84ee4..ceabfbf27346 100644 --- a/system/HTTP/SiteURIFactory.php +++ b/system/HTTP/SiteURIFactory.php @@ -173,6 +173,9 @@ private function parseRequestURI(): string parse_str($this->superglobals->server('QUERY_STRING'), $get); $this->superglobals->setGetArray($get); + // Sync $_REQUEST so that getVar() works correctly + $this->superglobals->syncRequest(); + return URI::removeDotSegments($path); } @@ -205,6 +208,9 @@ private function parseQueryString(): string parse_str($this->superglobals->server('QUERY_STRING'), $get); $this->superglobals->setGetArray($get); + // Sync $_REQUEST so that getVar() works correctly + $this->superglobals->syncRequest(); + return URI::removeDotSegments($path); } diff --git a/system/Superglobals.php b/system/Superglobals.php index 2175728e862e..31557ded5c42 100644 --- a/system/Superglobals.php +++ b/system/Superglobals.php @@ -456,4 +456,34 @@ public function setGlobalArray(string $name, array $array): void ), }; } + + /** + * Rebuilds $_REQUEST from $_GET, $_POST, and $_COOKIE according to PHP's + * request_order / variables_order ini setting. + * + * This is necessary when superglobals like $_GET are modified after the + * initial request population, since PHP does not automatically keep + * $_REQUEST in sync. + * + * @see https://www.php.net/manual/en/ini.core.php#ini.request-order + */ + public function syncRequest(): self + { + $requestOrder = ini_get('request_order') ?: ini_get('variables_order'); + + $this->request = []; + + foreach (str_split($requestOrder) as $type) { + match ($type) { + 'G' => $this->request = array_replace($this->request, $this->get), + 'P' => $this->request = array_replace($this->request, $this->post), + 'C' => $this->request = array_replace($this->request, $this->cookie), + default => null, + }; + } + + $_REQUEST = $this->request; + + return $this; + } }