web php

Superglobals

Superglobals are PHP arrays that are available almost everywhere without being passed into a function. In web PHP, they are how plain PHP exposes request data, server information, cookies, sessions, uploaded files, and environment values.

They are convenient, but they are also easy to misuse. Most superglobal values should be treated as untrusted input because they can come from the browser, proxy, server configuration, or environment.

The main superglobals

You will see these often:

$_GET      query string values, such as ?page=2
$_POST     form fields sent with application/x-www-form-urlencoded or multipart forms
$_COOKIE   cookies sent by the browser
$_FILES    uploaded file metadata and temporary file paths
$_SERVER   request/server metadata such as method, URI, host, and headers
$_SESSION  server-side session data after session_start()
$_ENV      environment variables imported into PHP
$_REQUEST  combined request data, usually GET, POST, and COOKIE depending on configuration

Prefer reading from the specific source you expect. If a value should come from the query string, use $_GET. If it should come from a submitted form, use $_POST. Avoid $_REQUEST in application code because it hides where a value came from.

Reading query input

Query strings are useful for filters, search terms, page numbers, and sort options. They are still user input.

PHP example
<?php

declare(strict_types=1);

$_GET['page'] = '3';

$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT, [
    'options' => ['default' => 1, 'min_range' => 1],
]);

echo 'Page: ' . $page . PHP_EOL;

// Prints:
// Page: 3

filter_input() reads from the original input source in a web request. In CLI examples, direct $_GET setup may not behave the same with filter_input(), so for small command-line demonstrations you can validate an array value yourself.

PHP example
<?php

declare(strict_types=1);

$query = ['page' => '3'];
$rawPage = $query['page'] ?? '1';
$page = filter_var($rawPage, FILTER_VALIDATE_INT, [
    'options' => ['default' => 1, 'min_range' => 1],
]);

echo 'Page: ' . $page . PHP_EOL;

// Prints:
// Page: 3

The principle is the same: read the expected source, validate the shape, and apply a safe default or error.

Reading request metadata

$_SERVER contains useful request metadata:

PHP example
<?php

declare(strict_types=1);

$server = [
    'REQUEST_METHOD' => 'POST',
    'REQUEST_URI' => '/login?next=/account',
    'HTTP_ACCEPT' => 'text/html',
];

$method = $server['REQUEST_METHOD'] ?? 'GET';
$path = parse_url($server['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/';
$accept = $server['HTTP_ACCEPT'] ?? '*/*';

echo $method . ' ' . $path . PHP_EOL;
echo 'Accept: ' . $accept . PHP_EOL;

// Prints:
// POST /login
// Accept: text/html

Be careful with headers such as Host, X-Forwarded-For, and X-Forwarded-Proto. They may be controlled by clients unless your proxy and trusted-proxy configuration are correct.

Sessions and cookies are different

Cookies are sent by the browser on each matching request. Sessions store data server-side and use a cookie, usually a session ID, to find that server-side data.

PHP example
<?php

declare(strict_types=1);

$_COOKIE['theme'] = 'dark';
$_SESSION['user_id'] = 42;

echo 'Theme cookie: ' . ($_COOKIE['theme'] ?? 'default') . PHP_EOL;
echo 'Session user: ' . ($_SESSION['user_id'] ?? 'guest') . PHP_EOL;

// Prints:
// Theme cookie: dark
// Session user: 42

Do not trust cookie values just because they came back from the browser. A user can edit their own cookies. Store sensitive authentication state in a server-side session or signed token, not in a plain cookie value.

Avoid superglobals deep in your code

Reading $_GET or $_POST in every service and helper makes code harder to test and reason about. A common pattern is to read superglobals near the edge of the application, validate them, then pass normal typed values deeper into the code.

PHP example
<?php

declare(strict_types=1);

function normaliseSearchTerm(array $query): string
{
    $term = trim((string) ($query['q'] ?? ''));

    return mb_substr($term, 0, 100);
}

echo normaliseSearchTerm(['q' => '  php arrays  ']) . PHP_EOL;

// Prints:
// php arrays

This function is easy to test because it accepts an array. It does not reach into $_GET itself.

What you should be able to do

After this lesson, you should be able to name the common superglobals, choose the right one for a value, avoid $_REQUEST, treat superglobal data as untrusted, and move request input into validated values before passing it deeper into an application.

Practice

Task: Normalise Request Input

Create a small PHP function that reads request-style arrays and returns validated values for a search page.

Requirements

  • Accept a query array instead of reading $_GET directly inside the function.
  • Read a search term named q.
  • Trim the search term and limit it to 100 characters.
  • Read a page number named page.
  • Validate the page number as an integer greater than or equal to 1.
  • Show one normal case and one edge case.
  • Add a short note explaining why this is easier to test than reading superglobals deep inside the function.

Check your work

The example should make the boundary clear: raw request data comes in, validated application values come out.

Show solution
PHP example
<?php

declare(strict_types=1);

/**
 * @return array{q: string, page: int}
 */
function normaliseSearchInput(array $query): array
{
    $term = trim((string) ($query['q'] ?? ''));
    $term = mb_substr($term, 0, 100);

    $page = filter_var($query['page'] ?? 1, FILTER_VALIDATE_INT, [
        'options' => ['default' => 1, 'min_range' => 1],
    ]);

    return [
        'q' => $term,
        'page' => $page,
    ];
}

$examples = [
    ['q' => '  php forms  ', 'page' => '2'],
    ['q' => str_repeat('a', 120), 'page' => '-5'],
];

foreach ($examples as $example) {
    $normalised = normaliseSearchInput($example);

    echo $normalised['q'] . ' | page ' . $normalised['page'] . PHP_EOL;
}

// Prints:
// php forms | page 2
// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | page 1

The function accepts an array instead of reaching into $_GET, so it can be tested with normal PHP values. A controller or front controller can read $_GET at the edge, pass it into this function, and then use the validated q and page values deeper in the application.