Superglobals ($_GET, $_POST, $_SERVER…)
debt(d5/e5/b7/t7)
Closest to 'specialist tool catches it' (d5). The detection_hints list phpstan, semgrep, and deptrac — these are specialist static analysis tools, not default linters. The code_pattern confirms they catch direct superglobal use in SQL/file paths or domain service classes, but this requires deliberate tool configuration and won't surface in a standard linter pass.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix says to filter at the controller boundary and pass clean values inward — but the common_mistakes show superglobals leaking into domain/service classes, session handling spread across many places, and direct use throughout the codebase. Introducing a request abstraction layer and pushing validation to the boundary while updating all call sites spans multiple files and components, landing solidly at e5.
Closest to 'strong gravitational pull' (e7). The applies_to covers web, cli, and queue-worker contexts — all PHP contexts — and the why_it_matters explains that direct superglobal access 'creates hidden input coupling and makes testing harder' throughout the codebase. Every new feature and test strategy is shaped by whether superglobals are accessed directly or through an abstraction, and the common_mistakes show this pattern spreading into domain/service layers, giving it a strong gravitational pull across the whole application.
Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The misconception field is explicit: $_REQUEST appears to be a convenient safe shorthand for $_GET and $_POST, but it merges GET, POST, and COOKIE with configurable and manipulable precedence — the 'obvious' convenience alternative is subtly unsafe. Additionally, $_SERVER['HTTP_HOST'] looks like a server-controlled value but is user-controllable, contradicting typical developer intuition about server variables. These are documented gotchas that contradict reasonable assumptions about how similar input concepts behave.
Also Known As
TL;DR
Explanation
PHP superglobals ($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER, $_SESSION, $_ENV, $_REQUEST) are accessible in any scope without declaration. Critically, all data from HTTP requests ($_GET, $_POST, $_COOKIE, $_REQUEST, and many $_SERVER keys) is attacker-controlled and must be validated and sanitised before use. $_SERVER['HTTP_HOST'], $_SERVER['HTTP_REFERER'], and $_SERVER['HTTP_X_FORWARDED_FOR'] are trivially spoofed. Never trust superglobal data without validation, and avoid $_REQUEST which merges GET, POST, and cookies.
Common Misconception
Why It Matters
Common Mistakes
- Reading $_GET/$_POST directly in domain or service classes — those layers should receive already-validated data.
- Trusting $_SERVER['HTTP_HOST'] for security decisions — it is user-controlled.
- Modifying $_SESSION directly in many places instead of through a session service — hard to trace and test.
- Not filtering and validating superglobal values at the application boundary before passing them inward.
Avoid When
- Never use $_REQUEST — it merges GET, POST, and COOKIE, making the input source ambiguous.
- Do not use extract($_GET) or extract($_POST) — it overwrites arbitrary variables with user-controlled values.
When To Use
- Access $_GET, $_POST, $_SERVER through a request abstraction layer rather than directly — makes testing and sanitisation consistent.
- Always validate and sanitise superglobal values before use — they contain raw user input.
Code Examples
// Superglobals accessed deep in domain logic:
class OrderService {
public function create(): Order {
$userId = $_SESSION['user_id']; // Coupled to HTTP context
$items = $_POST['items']; // Should be injected, not read directly
}
}
// PHP superglobals — always available, all scopes
// $_GET — URL query params
// $_POST — HTTP POST body (form data)
// $_COOKIE — HTTP cookies
// $_FILES — uploaded file metadata
// $_SERVER — server and request info
// $_SESSION — session data (after session_start())
// $_ENV — environment variables
// $_REQUEST — merged GET+POST+COOKIE (avoid — ambiguous)
// $GLOBALS — all global variables
// Safe access pattern:
$page = max(1, (int) ($_GET['page'] ?? 1));
$email = filter_var($_POST['email'] ?? '', FILTER_VALIDATE_EMAIL) ?: '';
// JSON API body:
$body = json_decode(file_get_contents('php://input'), true) ?? [];