PHP Superglobals
What Are Superglobals?
In simple terms: Superglobals are built-in PHP variables that contain information about the current request — the URL parameters, submitted form data, uploaded files, cookies, session data, and server details. They are available everywhere in your code without any special declaration. Technically: Superglobals are predefined arrays that PHP populates automatically at the start of each request. Unlike ordinary variables, they are accessible in every scope — global code, functions, and class methods — without the global keyword.
Why They Exist
A web application must react to what the visitor sends: which page was requested, what was typed into a form, which file was uploaded, which cookies the browser stored. PHP collects all of this from the HTTP request and the server environment and places it into superglobal arrays before your script starts running.
The Nine Superglobals
| Superglobal | Contains | Filled From | Lesson |
|---|---|---|---|
$_GET | URL query parameters | The query string (?page=2&sort=price) | $_GET |
$_POST | Form data sent with POST | The request body (form-encoded or multipart) | $_POST |
$_FILES | Uploaded files | Multipart form uploads | $_FILES |
$_COOKIE | Cookies sent by the browser | The Cookie request header | $_COOKIE |
$_SESSION | Data stored for the current user's session | Server-side session storage (after session_start()) | $_SESSION |
$_REQUEST | A combination of GET, POST (and possibly cookie) data | Built from the above, depending on configuration | $_REQUEST |
$_SERVER | Request and server information | The web server and PHP environment | $_SERVER |
$_ENV | Environment variables | The process environment (if enabled) | $_ENV |
$GLOBALS | All variables in the global scope | Your script's global variables | $GLOBALS |
Superglobals Are Available in Every Scope
Ordinary global variables are not visible inside functions (see Variables Scope). Superglobals are:
<?php
// Request: GET /search.php?q=php+arrays&page=2
function currentSearchTerm(): string
{
return trim($_GET['q'] ?? '');
}
function currentPage(): int
{
return max(1, (int) ($_GET['page'] ?? 1));
}
echo "Searching for: " . htmlspecialchars(currentSearchTerm()) . "\n";
echo "Page: " . currentPage() . "\n";
Output
Searching for: php arrays
Page: 2
Both functions read $_GET directly, without parameters or global. In the query string, + represents a space, and PHP decodes it automatically when filling $_GET.
Design note: Being able to read superglobals anywhere is convenient, but it hides where a function's data comes from and makes the function hard to test. A cleaner design reads request data once — at the "edge" of the application (for example, in a controller) — and passes the validated values to other functions as parameters.
How a Request Fills the Superglobals
Consider a form submission:
POST /contact.php?source=footer HTTP/1.1 Host: gocourse.in Content-Type: application/x-www-form-urlencoded Cookie: theme=dark name=Asha&email=asha%40example.com&message=HelloPHP fills the superglobals like this:
Superglobal Contents $_GET['source' => 'footer']$_POST['name' => 'Asha', 'email' => 'asha@example.com', 'message' => 'Hello']$_COOKIE['theme' => 'dark']$_SERVER['REQUEST_METHOD']'POST'$_SERVER['REQUEST_URI']'/contact.php?source=footer'$_SERVER['HTTP_HOST']'gocourse.in'A request can contain query parameters and a body at the same time, so
$_GETand$_POSTcan both have data. Values are URL-decoded automatically (%40becomes@).
All Input Is Untrusted
Everything in
$_GET,$_POST,$_COOKIE,$_FILES,$_REQUEST, and most of$_SERVERcomes from the client. Users — and attackers — can send any value, regardless of what your HTML form allows:
- Hidden fields and dropdowns can be changed in the browser's developer tools.
- Requests can be sent with tools such as
curlwithout any form at all.- Headers such as
User-Agent,Referer, andHostcan contain anything. This leads to three essential rules:
- Validate every input: check type, format, length, and allowed values.
- Escape every output for its context:
htmlspecialchars()for HTML, prepared statements for SQL.- Never trust client data for security decisions (prices, user IDs, permissions) — look them up on the server.
Example: Validating Input
<?php // Request: GET /products.php?category=books&page=abc&sort=price_desc $allowedSorts = ['newest', 'price_asc', 'price_desc']; $category = preg_match('/^[a-z-]{1,30}$/', $_GET['category'] ?? '') ? $_GET['category'] : 'all'; $page = filter_var($_GET['page'] ?? 1, FILTER_VALIDATE_INT, ['options' => ['min_range' => 1]]) ?: 1; $sort = in_array($_GET['sort'] ?? '', $allowedSorts, true) ? $_GET['sort'] : 'newest'; echo "Category: $category, page: $page, sort: $sort\n";Output
Category: books, page: 1, sort: price_desc
categorymust match a simple pattern (lowercase letters and hyphens).pagemust be a positive integer;'abc'is rejected and replaced with1.sortmust be one of the allowed values. Validation is covered in depth in the PHP Forms section.
Values Are Strings (or Arrays of Strings)
Data from
$_GET,$_POST, and$_COOKIEalways arrives as strings — even numbers. A parameter written with brackets in its name arrives as an array:<?php // Request: GET /filter.php?min=500&tags[]=new&tags[]=sale var_dump($_GET['min']); var_dump($_GET['tags']);Output
string(3) "500" array(2) { [0]=> string(3) "new" [1]=> string(4) "sale" }Because a parameter can be a string or an array, code that expects a string must check its type. Passing an unexpected array to string functions causes a
TypeError(see $_GET).
Superglobals in the Command Line
When a script runs from the command line (
php script.php), there is no HTTP request:
$_GET,$_POST,$_COOKIE, and$_FILESare empty arrays.$_SERVER['argv']contains the command-line arguments, and$_SERVER['argc']their count.<?php // Run: php report.php 2026-10 csv echo "Script: {$_SERVER['argv'][0]}\n"; echo "Month: " . ($_SERVER['argv'][1] ?? 'current') . "\n"; echo "Format: " . ($_SERVER['argv'][2] ?? 'txt') . "\n";Output
Script: report.php Month: 2026-10 Format: csvSee PHP Command Line (CLI).
Configuration That Affects Superglobals
php.iniSettingEffect variables_orderWhich superglobals are populated ( "GPCS"in the recommendedphp.inifiles;Eis omitted, so$_ENVis usually empty — usegetenv()instead)request_orderWhich data $_REQUESTcombines, and in which order ("GP"in the recommended files)post_max_sizeMaximum size of a POST body; if exceeded, $_POSTand$_FILESare emptymax_input_varsMaximum number of input variables (default 1000); extra fields are dropped with a warning upload_max_filesizeMaximum size of each uploaded file
Superglobals in Frameworks
Frameworks wrap superglobals in request objects — for example,
$request->query('page')in Laravel or$request->query->get('page')in Symfony. These objects make code testable (a fake request can be passed in) and provide helpers for validation. Understanding the raw superglobals explains what these objects do internally.
Common Mistakes
Reading Input Without Defaults
Effect: "Undefined array key" warnings when a parameter is missing. Fix:
$_GET['page'] ?? 1.Printing Input Without Escaping
Effect: Cross-site scripting (XSS). Fix:
htmlspecialchars($_GET['q'] ?? '').Using Input Directly in SQL
Effect: SQL injection. Fix: Prepared statements (see PDO Prepared Statements).
Trusting Client-Supplied Values
Effect: Users manipulate prices, IDs, or roles. Fix: Recalculate and authorize everything on the server.
Modifying Superglobals
Effect: Other parts of the application see changed "input", which is confusing and hard to debug. Fix: Copy values into variables, validate them, and work with those.
Best Practices
- Read request data at the edge of your application, validate it, and pass clean values onward.
- Use
??defaults for optional parameters.- Validate with
filter_var(), allow-lists, and patterns; escape all output.- Prefer
$_GETand$_POSTover$_REQUESTso the data source is explicit.- Treat superglobals as read-only. Official reference: https://www.php.net/manual/en/language.variables.superglobals.php