-
Notifications
You must be signed in to change notification settings - Fork 6
Add SESSION hash support to Request class #147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 2 commits
69edcc8
2fcef08
ae74064
eec0b4d
e3cb224
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -64,12 +64,13 @@ public static function getMethod() | |||||||||||||||||||||||||||||||||||||
| * - cookie $_COOKIE | ||||||||||||||||||||||||||||||||||||||
| * - env $_ENV | ||||||||||||||||||||||||||||||||||||||
| * - server $_SERVER | ||||||||||||||||||||||||||||||||||||||
| * - session $_SESSION (returns default if no active session) | ||||||||||||||||||||||||||||||||||||||
| * - method via current $_SERVER['REQUEST_METHOD'] | ||||||||||||||||||||||||||||||||||||||
| * - default $_REQUEST | ||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||
| * @param string $name Variable name | ||||||||||||||||||||||||||||||||||||||
| * @param mixed $default Default value if the variable does not exist | ||||||||||||||||||||||||||||||||||||||
| * @param string $hash Source of variable value (POST, GET, FILES, COOKIE, METHOD) | ||||||||||||||||||||||||||||||||||||||
| * @param string $hash Source of variable value (GET, POST, FILES, COOKIE, ENV, SERVER, SESSION, METHOD, DEFAULT/REQUEST) | ||||||||||||||||||||||||||||||||||||||
| * @param string $type Return type for the variable (INT, FLOAT, BOOLEAN, WORD, | ||||||||||||||||||||||||||||||||||||||
| * ALPHANUM, CMD, BASE64, STRING, ARRAY, PATH, NONE) For more | ||||||||||||||||||||||||||||||||||||||
| * information see FilterInput::clean(). | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -106,6 +107,13 @@ public static function getVar($name, $default = null, $hash = 'default', $type = | |||||||||||||||||||||||||||||||||||||
| case 'SERVER': | ||||||||||||||||||||||||||||||||||||||
| $input = &$_SERVER; | ||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||
| case 'SESSION': | ||||||||||||||||||||||||||||||||||||||
| if (session_status() !== PHP_SESSION_ACTIVE) { | ||||||||||||||||||||||||||||||||||||||
| $input = []; | ||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| $input = &$_SESSION; | ||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+110
to
+116
|
||||||||||||||||||||||||||||||||||||||
| default: | ||||||||||||||||||||||||||||||||||||||
| $input = &$_REQUEST; | ||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -385,9 +393,11 @@ public static function hasVar($name, $hash = 'default') | |||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||
| * Set a variable in one of the request variables | ||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||
| * For SESSION, the write is silently skipped if no session is active. | ||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||
| * @param string $name Name | ||||||||||||||||||||||||||||||||||||||
| * @param string $value Value | ||||||||||||||||||||||||||||||||||||||
| * @param string $hash Hash | ||||||||||||||||||||||||||||||||||||||
| * @param string $hash Hash (GET, POST, REQUEST, COOKIE, FILES, ENV, SERVER, SESSION, METHOD) | ||||||||||||||||||||||||||||||||||||||
| * @param bool $overwrite Boolean | ||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||
| * @return string Previous value | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -437,6 +447,11 @@ public static function setVar($name, $value = null, $hash = 'method', $overwrite | |||||||||||||||||||||||||||||||||||||
| case 'SERVER': | ||||||||||||||||||||||||||||||||||||||
| $_SERVER[$name] = $value; | ||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||
| case 'SESSION': | ||||||||||||||||||||||||||||||||||||||
| if (session_status() === PHP_SESSION_ACTIVE) { | ||||||||||||||||||||||||||||||||||||||
| $_SESSION[$name] = $value; | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+449
to
+450
|
||||||||||||||||||||||||||||||||||||||
| if (session_status() === PHP_SESSION_ACTIVE) { | |
| $_SESSION[$name] = $value; | |
| if (function_exists('session_status') && defined('PHP_SESSION_ACTIVE')) { | |
| if (session_status() === PHP_SESSION_ACTIVE) { | |
| $_SESSION[$name] = $value; | |
| } |
Copilot
AI
Mar 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SESSION support was added to setVar(), but the method’s docblock doesn’t mention SESSION or the no-op behavior when no session is active. Please update the setVar() documentation to include SESSION and clarify what happens when the session isn’t active.
Copilot
AI
Mar 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same concern as getVar(): the SESSION branch uses session_status()/PHP_SESSION_ACTIVE, which can be undefined if the session extension is disabled. Guarding here would prevent fatals and let Request::get('session') degrade to an empty array as intended.
| case 'SESSION': | |
| if (session_status() !== PHP_SESSION_ACTIVE) { | |
| $input = []; | |
| break; | |
| } | |
| case 'SESSION': | |
| if (!function_exists('session_status') || !defined('PHP_SESSION_ACTIVE')) { | |
| $input = []; | |
| break; | |
| } | |
| if (session_status() !== PHP_SESSION_ACTIVE) { | |
| $input = []; | |
| break; | |
| } | |
| if (!isset($_SESSION)) { | |
| $input = []; | |
| break; | |
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -17,6 +17,10 @@ class RequestTest extends \PHPUnit\Framework\TestCase | |||||||||||||||||||||||||||||||||
| protected function setUp(): void | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| $this->object = new Request; | ||||||||||||||||||||||||||||||||||
| // Ensure a consistent session state for tests that need it | ||||||||||||||||||||||||||||||||||
| if (session_status() !== PHP_SESSION_ACTIVE) { | ||||||||||||||||||||||||||||||||||
| session_start(); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||
|
|
@@ -25,6 +29,10 @@ protected function setUp(): void | |||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||
| protected function tearDown(): void | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| // Restore active session state after each test | ||||||||||||||||||||||||||||||||||
| if (session_status() !== PHP_SESSION_ACTIVE) { | ||||||||||||||||||||||||||||||||||
| session_start(); | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
| // Restore active session state after each test | |
| if (session_status() !== PHP_SESSION_ACTIVE) { | |
| session_start(); | |
| } | |
| // Do not modify session state here; individual tests or setUp() manage it. | |
| $this->object = null; |
Copilot
AI
Mar 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
requireActiveSession() only checks session_status() but never attempts to start the session, so its skip message can be misleading and it relies on setUp() having already started the session. If you move session initialization out of setUp(), update this helper to attempt to start the session (and skip only if activation fails).
| { | |
| { | |
| if (session_status() === PHP_SESSION_ACTIVE) { | |
| return; | |
| } | |
| // Try to start a session if one is not already active. | |
| if (headers_sent()) { | |
| $this->markTestSkipped('Cannot start a session: headers already sent in this environment.'); | |
| } | |
| try { | |
| @session_start(); | |
| } catch (\Throwable $exception) { | |
| $this->markTestSkipped('Cannot start a session in this environment: ' . $exception->getMessage()); | |
| } |
Copilot
AI
Mar 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
session_destroy() clears session data but does not actually close the session in the current process, so session_status() can remain PHP_SESSION_ACTIVE. This makes the assertion in closeTestSession() unreliable and can leave a session active across tests. Prefer explicitly closing the session (e.g., call session_write_close()/session_abort() after clearing) and only use session_destroy() if you also close the session afterward.
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
Outdated
Copilot
AI
Mar 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test assumes the session doesn’t already contain $varname. If a prior run/environment leaves the key set, the final assertArrayNotHasKey() can fail even though setVar() correctly skipped writing. Make the test deterministic by unsetting the key before session_write_close() and after session_start(), or by using a fresh session id / clearing $_SESSION for the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial
Add the inactive-session hasVar() case.
The new behavior path is “treat SESSION as empty when no session is active,” but this test only covers the active-session branch. A direct assertFalse(Request::hasVar(..., 'session')) after closing the session would lock that edge case down too. As per coding guidelines, tests/**/*.php: Review test code for proper assertions, test isolation, and edge case coverage.
🧰 Tools
🪛 PHPMD (2.15.0)
[error] 427-440: testHasVarSession accesses the super-global variable $_SESSION. (undefined)
(Superglobals)
[error] 427-440: testHasVarSession accesses the super-global variable $_SESSION. (undefined)
(Superglobals)
[error] 433-433: Avoid using static access to class '\Xmf\Request' in method 'testHasVarSession'. (undefined)
(StaticAccess)
[error] 435-435: Avoid using static access to class '\Xmf\Request' in method 'testHasVarSession'. (undefined)
(StaticAccess)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tests/unit/RequestTest.php` around lines 427 - 440, Add an assertion for the
inactive-session branch in testHasVarSession: after unsetting
$_SESSION[$varname] and calling $this->closeTestSession() (use the existing
startTestSession/closeTestSession helpers), call Request::hasVar($varname,
'session') and assertFalse to verify SESSION is treated as empty when no session
is active; keep the existing try/finally cleanup and ensure the inactive
assertion runs after the session is closed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The getVar() docblock now advertises SESSION support, but the proxy methods (e.g., getInt/getFloat/getBool/etc.) still document only POST/GET/FILES/COOKIE/METHOD even though they accept the same $hash values via getVar(). Consider updating those docblocks too so the public API documentation stays consistent.