Phase 2 · Web FundamentalsModule 11~42 min read

Superglobals & Application State

Use PHP's request data, cookies, and sessions to carry intentional state across stateless HTTP requests.

What you'll learn

HTTP forgets each request as soon as it finishes. Cookies and sessions let an application carry intentional state forward without pretending the protocol itself remembers.

  • Use PHP superglobals defensively
  • Create minimal, well-scoped cookies
  • Store server-side state in a session
  • Implement one-time flash messages
  • Regenerate and destroy sessions correctly
  • Decide what should remain stateless

Know the request data surfaces

SuperglobalContainsTypical use
$_GETQuery-string fieldsSearch, filters, pagination
$_POSTURL-encoded or multipart form fieldsSubmitted commands
$_SERVERRequest and server metadataMethod, path, selected headers
$_COOKIEClient-supplied cookie valuesRead a preference or session identifier
$_FILESUploaded-file metadataValidate and move uploads
$_SESSIONServer-side session dataIdentity, CSRF state, flash messages
$_ENVEnvironment values when configuredRuntime configuration

Watch out

Superglobals are convenient, not trustworthy. Copy the small values a use case needs into explicit validated variables instead of passing $_POST or $_SERVER through the application.

Cookies are client-held strings

A server sets a cookie in a response header; the browser may return it on later matching requests. Cookies are size-limited, sent repeatedly, and controlled by the client—store identifiers and preferences, not trusted authorization facts or sensitive records.

theme-cookie.php
<?php

declare(strict_types=1);

setcookie('theme', 'dark', [
    'expires' => time() + 60 * 60 * 24 * 30,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);

$theme = in_array($_COOKIE['theme'] ?? '', ['light', 'dark'], true)
    ? $_COOKIE['theme']
    : 'light';
AttributeProtection
SecureSend only over HTTPS
HttpOnlyHide from ordinary client-side JavaScript
SameSiteRestrict cross-site sending and reduce CSRF exposure
Path / DomainLimit which requests receive the cookie
Expires / Max-AgeChoose session-only or persistent lifetime

Sessions keep state on the server

PHP normally stores session data server-side and gives the browser only a random session identifier cookie. Start the session before output, then read and write $_SESSION.

cart-session.php
<?php

declare(strict_types=1);

session_set_cookie_params([
    'lifetime' => 0,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);

session_start();

$_SESSION['cart_count'] = ($_SESSION['cart_count'] ?? 0) + 1;
echo 'Items: ' . $_SESSION['cart_count'];

Key idea

A session is not a database. Keep it small and temporary: user ID, CSRF token, a checkout step, or a flash message. Durable business records belong in persistent storage.

One-time flash messages

A flash message is written before a redirect, read on the next request, and removed immediately. It makes Post/Redirect/Get feel continuous.

flash.php
<?php

function flash(string $key, ?string $message = null): ?string
{
    if ($message !== null) {
        $_SESSION['_flash'][$key] = $message;
        return null;
    }

    $value = $_SESSION['_flash'][$key] ?? null;
    unset($_SESSION['_flash'][$key]);

    return is_string($value) ? $value : null;
}

// Before redirect:
flash('success', 'Profile updated.');

// On the redirected page:
$message = flash('success');

Manage the session lifecycle

Regenerate the session identifier after privilege changes such as login. On logout, remove session data, expire the session cookie, and destroy server-side state.

session-lifecycle.php
<?php

// After successful credential verification:
session_regenerate_id(true);
$_SESSION['user_id'] = 42;

// During logout:
$_SESSION = [];

if (ini_get('session.use_cookies')) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', [
        'expires' => time() - 42000,
        'path' => $params['path'],
        'domain' => $params['domain'],
        'secure' => $params['secure'],
        'httponly' => $params['httponly'],
        'samesite' => 'Lax',
    ]);
}

session_destroy();

Sessions do not replace CSRF protection

A browser automatically sends its session cookie. State-changing form requests still need a CSRF token, and sensitive actions still need authorization checks.

Choose state intentionally

  • Keep search filters in the URL so results are shareable
  • Keep durable orders and profiles in a database
  • Keep transient identity and workflow state in a session
  • Keep harmless client preferences in cookies after validation
  • Do not duplicate the same authority across cookie, session, URL, and database

Recap & quick check

Key takeaways

  • Superglobals expose request/runtime data but do not make it trusted.
  • Cookies are client-held strings; minimize and validate them.
  • Sessions keep temporary server-side state linked by a random identifier.
  • Flash data lives for one following request and works naturally with redirects.
  • Regenerate on login and fully clear cookie plus server state on logout.

Quick check

1. Where is ordinary PHP session data stored?

2. When should the session ID be regenerated?

3. What is flash data for?

4. Does a session automatically prevent CSRF?