Environment Variables
debt(d9/e3/b5/t9)
Closest to 'silent in production until users hit it' (d9). The detection_hints indicate automated detection is 'no', and tools listed (phpinfo, php-fpm-status) require manual inspection. The symptom — getenv() silently returning empty — only surfaces at runtime when application logic fails, with no compiler, linter, or static analysis catching the missing clear_env=no in FPM pool config. Users hit a mysterious empty-value bug in production with no warnings.
Closest to 'simple parameterised fix' (e3). The quick_fix describes adding env[APP_ENV] = production lines to the PHP-FPM pool config or setting vars in /etc/environment — a small targeted change in one or two config files. However a restart is also required, and .env/git hygiene issues may need addressing across repos, nudging slightly above e1 but remaining localised.
Closest to 'persistent productivity tax' (b5). The applies_to covers both web and CLI contexts, and the tags span linux, php, devops, and security — a broad cross-cutting concern. Every deployment, environment promotion, and secret rotation must account for how env vars flow through FPM pool config. It slows multiple work streams (devops, backend dev, security review) without being fully architectural.
Closest to 'catastrophic trap' (t9). The misconception field explicitly names the trap: developers universally assume PHP-FPM inherits shell environment variables as other runtimes do, but clear_env=yes is the default, silently discarding all system env vars. The 'obvious' approach — setting vars in shell/systemd and calling getenv() — always returns empty in FPM. This directly contradicts behaviour in CLI PHP, Apache mod_php, and virtually every other runtime, making it a maximum-severity cognitive trap.
Also Known As
TL;DR
Explanation
Environment variables are set in the shell (export VAR=value), in process supervisors (systemd Environment=, Supervisor environment=), in Docker (ENV, --env), or in .env files loaded at application startup. In PHP: getenv('VAR'), $_ENV['VAR'], or $_SERVER['VAR']. PHP-FPM does not automatically inherit the server environment — use env[VAR] = $VAR in the FPM pool config or clear_env=no. Variables are process-scoped: a child process cannot modify the parent's environment.
Common Misconception
Why It Matters
Common Mistakes
- clear_env=yes (default) in PHP-FPM — getenv() returns empty for all system env vars.
- Storing secrets in .env files committed to git — .env must be in .gitignore.
- Using putenv() to set vars in PHP — only affects the current process, not parent or sibling processes.
- Not restarting PHP-FPM after changing environment variables — processes inherit env at startup only.
Code Examples
; PHP-FPM default — clears all environment:
; /etc/php-fpm.d/www.conf:
; clear_env = yes (default)
; PHP code:
echo getenv('DB_HOST'); // Returns false/empty!
// Mystery: var is set in /etc/environment but FPM cleared it
; Option 1 — explicit pass-through in FPM pool:
clear_env = no ; Pass all environment vars through
; Option 2 — explicit declarations (more secure):
env[DB_HOST] = $DB_HOST
env[DB_PASS] = $DB_PASS
env[APP_ENV] = production
; PHP:
$host = getenv('DB_HOST'); // Now works
$host = $_ENV['DB_HOST']; // Also works
$host = $_SERVER['DB_HOST']; // Also works