Say that any $_ENV write in worker mode outlives its request - #366
Merged
diolektor merged 1 commit intoSep 19, 2026
Merged
Conversation
Docs: - The `$_ENV` section described the pinning only from the bootstrap side, so a reader takes a handler write for request state. Any write survives: every later request that worker serves reads it, and so does a request multiplexed alongside the writer while it is parked. Name the per-request homes that do work, and what disqualifies a framework's. - The fiber page promised full isolation and listed superglobals as a class, which was never true of `$_ENV`. List the six names the scheduler actually parks and say that what is left is shared while requests overlap. - Scope the worker page's reset list to `auto_globals_jit=1`, the setting the carve-out has always depended on and never stated.
diolektor
deleted the
fix/worker-mode-docs-omit-that-env-writes-are-worker-global
branch
September 19, 2026 19:49
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
docs/php/superglobals.mddescribed worker-mode$_ENVpinning from one side only — "writes your bootstrap makes there stay visible to every request that worker serves", and, a paragraph later, "$_ENVholds the process values plus whatever your bootstrap added". Both sentences are true, and both read as though the bootstrap is what makes a write survive.Nothing distinguishes a bootstrap write from any other. Pinning the array is the whole of the mechanism, so
$_ENV['tenant_id'] = $request->tenant();inside a request handler stays there for the rest of that worker's life: every later request that worker serves reads it, and so does a request the worker picks up while the writer is parked at a suspension point, because$_ENVis deliberately left out of the state a suspended request carries with it. None of it is reported — no warning, no log line, only a request reading a value some other request set.The behaviour is intentional and is not changed here; what was missing was the second half of its description. The fiber page meanwhile asserted the opposite — "Each fiber's PHP state — superglobals, response headers, output buffers, VM stack — is saved on suspension and restored on resumption. Fibers are fully isolated from each other" — on the very page the
$_ENVnote sends readers to for the list of suspension points.What changed
docs/php/superglobals.mdgains a note saying that$_ENVin worker mode is worker state rather than request state, covering both the later-request and the multiplexed-neighbour case, and then says where a per-request value belongs instead:$_SERVER, which is rebuilt per request and travels with its own request across a suspension; whatever your framework scopes to the request, with the condition that disqualifies one — a container binding or a request stack set up once during bootstrap is worker state, with the same reach as$_ENV; and the request object's attributes container, for as long as that object is passed along, becauseoxphp_http_request()builds a freshRequest, and a fresh empty container with it, on every call.docs/features/fiber-multiplexing.mdnow lists the six superglobals the scheduler actually parks per fiber ($_GET,$_POST,$_COOKIE,$_SERVER,$_FILES,$_REQUEST) instead of naming the class, says that what is not on that list is shared while two requests overlap on a thread, and states the$_ENVcarve-out. Enumerating rather than quantifying is deliberate:$_ENVis not the only PHP state outside the parked set, so any "the one exception" phrasing would have been false in a different direction.docs/features/worker-mode.mdgains a$_ENVbullet in What Persists — the list an operator reads as the inventory of surviving state, and the one place$_ENVwas absent from — and its "Between requests" reset list now names the setting the carve-out has always depended on, PHP's defaultauto_globals_jit=1.No behaviour changes — documentation only.
Verification
scripts/gen-llms-txt.sh --check— regenerated and up to date (58 pages).scripts/check-links.sh— 641 in-repo links, none broken, the new cross-page anchors included.cargo fmt -- --check,cargo clippy --no-default-features -- -D warnings,cargo test --no-default-features— clean. No Rust or C source is touched on this branch.$_ENVfrom inside a request handler and requires the value back on a later request, and thefilter_inputtest asserts the same from the other side.filter_input(INPUT_ENV, …)note rests on was re-read at both supported PHP versions:php_auto_globals_create_env()leaves the$_ENVsymbol-table entry and the engine's own copy sharing one array, so copy-on-write separates them at the first userland write — whoever makes it. That is why the filter extension keeps returning environment values after a handler has written to$_ENV, and the note now says so without attributing the write to the bootstrap.