Skip to content

Conversation

@xavierleune
Copy link
Contributor

Hi,

This PR fixes #1931, it handles $_REQUEST in worker mode correctly when auto_globals_jit is enabled (default configuration for PHP).
Some concerns were raised in the comments of the issue regarding performance. This implementation should make sure that request is created only if used.

However if a previous execution plan already used _REQUEST, all subsequent requests will create it. So the concern is "kindof" mitigated.

Let me know if you have any suggestion to improve this.

@xavierleune xavierleune force-pushed the fix/1931-request-worker-mode-jit branch 2 times, most recently from 9ab03f0 to d677931 Compare January 22, 2026 15:07
Copy link
Member

@dunglas dunglas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dunglas dunglas requested a review from Copilot January 22, 2026 15:45
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug in worker mode where the $_REQUEST superglobal was not being properly reinitialized between requests when PHP's auto_globals_jit is enabled (the default configuration). The fix ensures $_REQUEST contains only the current request's data, not stale data from previous requests.

Changes:

  • Modified frankenphp_reset_super_globals() to properly handle JIT auto globals by re-initializing them if they exist in the symbol table, or re-arming them for future use
  • Added comprehensive test coverage including basic and conditional access scenarios to verify $_REQUEST correctness across multiple requests

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
frankenphp.c Updated superglobal reset logic to handle $_REQUEST initialization in worker mode with JIT auto globals
frankenphp_test.go Added test functions to verify $_REQUEST behavior in both module and worker modes
testdata/request-superglobal.php Test script that outputs $_REQUEST, $_GET, and $_POST to verify correct merging
testdata/request-superglobal-conditional.php Test script for conditional $_REQUEST access to verify re-arm mechanism
testdata/request-superglobal-conditional-include.php Included file that validates $_REQUEST contains only current request data

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@xavierleune xavierleune force-pushed the fix/1931-request-worker-mode-jit branch from d677931 to ae22ddc Compare January 23, 2026 09:38
@xavierleune
Copy link
Contributor Author

Is the failing test the kind of situation where we should try turning it off and on again ? :D

Comment on lines +132 to +140
/* JIT globals ($_REQUEST, $GLOBALS) need special handling:
* - If in symbol_table: re-initialize with current request data
* - If not: re-arm for potential future use during include */
if (zend_hash_exists(&EG(symbol_table), auto_global->name)) {
auto_global->armed =
auto_global->auto_global_callback(auto_global->name);
} else {
auto_global->armed = true;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea to only reset $_REQUEST if it's present in the symbol table.

Do we need to reset $_GLOBALS as well though? Couldn't that have other side effects?

Comment on lines +344 to +345
req := httptest.NewRequest("GET", fmt.Sprintf("http://example.com/request-superglobal-conditional.php?val=%d", i), nil)
body, _ := testRequest(req, handler, t)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
req := httptest.NewRequest("GET", fmt.Sprintf("http://example.com/request-superglobal-conditional.php?val=%d", i), nil)
body, _ := testRequest(req, handler, t)
body, _:= testGet(fmt.Sprintf("http://example.com/request-superglobal-conditional.php?val=%d", i), handler, t)

Comment on lines +350 to +351
req := httptest.NewRequest("GET", fmt.Sprintf("http://example.com/request-superglobal-conditional.php?use_request=1&val=%d", i), nil)
body, _ := testRequest(req, handler, t)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
req := httptest.NewRequest("GET", fmt.Sprintf("http://example.com/request-superglobal-conditional.php?use_request=1&val=%d", i), nil)
body, _ := testRequest(req, handler, t)
body, _ := testGet(fmt.Sprintf("http://example.com/request-superglobal-conditional.php?use_request=1&val=%d", i), handler, t)

Comment on lines +353 to +359
// $_REQUEST should have ONLY current request's data (2 keys: use_request and val)
assert.Contains(t, body, "REQUEST_COUNT:2")
// Verify current request data is present
assert.Contains(t, body, fmt.Sprintf("'val' => '%d'", i))
assert.Contains(t, body, "'use_request' => '1'")
// Critical: verify $_REQUEST has the CURRENT request's val, not stale data
assert.Contains(t, body, "VAL_CHECK:MATCH", "BUG: $_REQUEST contains stale data from previous request! Body: "+body)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// $_REQUEST should have ONLY current request's data (2 keys: use_request and val)
assert.Contains(t, body, "REQUEST_COUNT:2")
// Verify current request data is present
assert.Contains(t, body, fmt.Sprintf("'val' => '%d'", i))
assert.Contains(t, body, "'use_request' => '1'")
// Critical: verify $_REQUEST has the CURRENT request's val, not stale data
assert.Contains(t, body, "VAL_CHECK:MATCH", "BUG: $_REQUEST contains stale data from previous request! Body: "+body)
assert.Contains(t, body, "REQUEST_COUNT:2", "$_REQUEST should have ONLY current request's data (2 keys: use_request and val)")
assert.Contains(t, body, fmt.Sprintf("'val' => '%d'", i), "request data is not present")
assert.Contains(t, body, "'use_request' => '1'")
assert.Contains(t, body, "VAL_CHECK:MATCH", "BUG: $_REQUEST contains stale data from previous request! Body: "+body)

@AlliBalliBaba
Copy link
Contributor

The failing test was testing super globals reset,.so likely related to this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

In worker mode, $_REQUEST is incorrectly cached

3 participants