Repository navigation
Bug: getVar() behaves inconsistently with GET parameters #9872
Description
Activity
- addedbugVerified issues on the current code behavior or pull requests that will fix themVerified issues on the current code behavior or pull requests that will fix them
on Jan 5, 2026 I don't think auto-synchronization is necessary. Since this is a test problem, it is worth calling the method only in certain cases. In production, everything should work as intended.
I'm not sure, but a similar behavior can be seen when merging ENV and SERVER. If we change the value, it may remain the same in another array.
This is not a test-related problem. The test only serves as an example to reliably reproduce the issue.
We are modifying $_GET, but
getVar()relies on $_REQUEST, which has not been modified.The core issue is how
getVar()is currently handled. While we already discourage users from using it,$validation->withRequest()is still available, and it may not work correctly when validating parameters that originate from $_GET.I'm not sure, but a similar behavior can be seen when merging ENV and SERVER. If we change the value, it may remain the same in another array.
The difference with $_REQUEST is that this superglobal is expected to contain values combined from $_GET, $_POST, and $_COOKIE (depending on configuration). However, it is populated only once at the beginning of the request. Since we modify $_GET early in the request lifecycle, those changes are not reflected in $_REQUEST.
Reacted by Pooya ParsaI understand the problem. That's why I mentioned the SERVER.
I'm worried about the reverse problem - we've changed the REQUEST or GET and expect the other array not to change as intended in PHP. As a result, we will get synchronization.
Will
getVar()be eventually get deprecated? If not, can we not just return a merged array from the 3 other superglobals that always get updated and leave $_REQUEST as is?I'm not proposing permanent synchronization, as that is not how superglobals are intended to work. The proposal is to synchronize $_REQUEST only once, at a single, well-defined point during the request lifecycle in
SiteURIFactory:CodeIgniter4/system/HTTP/SiteURIFactory.php
Lines 171 to 175 in 11f0130
// Update our global GET for values likely to have been changed parse_str($this->superglobals->server('QUERY_STRING'), $get); $this->superglobals->setGetArray($get); The alternative would be to change how
$validation->withRequest()works by avoidinggetVar()and replacing the call to it with the merged $_GET, $_POST, and $_COOKIE data.However, a one-time synchronization seems like the better approach. It is more reliable and makes
getVar()work correctly.@paulbalandan That is also a valid solution. This would eventually allow us to get rid of
getVar(), which is probably a good idea.- added 2 commits that reference this issue
on May 18, 2026 - added 7 commits that reference this issue
on Sep 25, 2026 - added 2 commits that reference this issue
on Oct 8, 2026
PHP Version
8.4
CodeIgniter4 Version
4.6.4
CodeIgniter4 Installation Method
Composer (using
codeigniter4/appstarter)Which operating systems have you tested for this bug?
macOS
Which server did you use?
cli-server (PHP built-in webserver)
Environment
development
Database
What happened?
In some cases, using
$validator->withRequest()will not work correctly. Let's consider this test:CodeIgniter4/tests/system/HTTP/SiteURIFactoryDetectRoutePathTest.php
Lines 226 to 241 in 11f0130
As you may notice in the above test,
SiteURIFactoryupdates some superglobals, here:CodeIgniter4/system/HTTP/SiteURIFactory.php
Lines 162 to 175 in 11f0130
The problem is that while
$_SERVER['QUERY_STRING']and$_GETare being updated, the$_REQUESTisn't. And$_REQUESTis needed to makegetVar()work correctly.CodeIgniter4/system/Validation/Validation.php
Lines 505 to 527 in 11f0130
CodeIgniter4/system/HTTP/IncomingRequest.php
Lines 496 to 506 in 11f0130
Steps to Reproduce
Expected Output
Validation method
$validator->withRequest()should work correctly.The most tempting solution is to add
syncRequestAfterGetChange()toSuperglobalsand call it fromSiteURIFactorywhenever$_GETis modified. This would keep$_REQUESTsynchronized with current values.The downside is it introduces "magic" behavior that violates standard PHP semantics where
$_REQUESTis populated once and never auto-updated. However, since we update$_GETas a "standard", behavior, then updating$_REQUESTmay be acceptable?I was thinking about something like this:
But I'm unsure if this is the right direction.
Anything else?
https://forum.codeigniter.com/showthread.php?tid=93652