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
| Superglobal | Contains | Typical use |
|---|---|---|
$_GET | Query-string fields | Search, filters, pagination |
$_POST | URL-encoded or multipart form fields | Submitted commands |
$_SERVER | Request and server metadata | Method, path, selected headers |
$_COOKIE | Client-supplied cookie values | Read a preference or session identifier |
$_FILES | Uploaded-file metadata | Validate and move uploads |
$_SESSION | Server-side session data | Identity, CSRF state, flash messages |
$_ENV | Environment values when configured | Runtime configuration |
Watch out
$_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.
<?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';| Attribute | Protection |
|---|---|
Secure | Send only over HTTPS |
HttpOnly | Hide from ordinary client-side JavaScript |
SameSite | Restrict cross-site sending and reduce CSRF exposure |
Path / Domain | Limit which requests receive the cookie |
Expires / Max-Age | Choose 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.
<?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
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.
<?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.
<?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
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?