The web has a short memory. Every time a browser asks for a page, the server treats the request as completely new; it doesn't automatically know that the same person just logged in or added something to their basket. That's how the HTTP protocol works: each request stands alone.
To remember a visitor between pages, PHP offers two tools. A cookie is a small piece of text the server asks the browser to store and send back with every later request. A session keeps data on the server and gives the browser just one cookie containing a random session ID, so PHP can find that visitor's data again.
In this lesson you'll store data in sessions, build a small shopping basket and a login, set and read cookies for simple preferences, and learn the security settings that keep both safe.
Starting a session
<?php
session_start();
$_SESSION['visits'] = ($_SESSION['visits'] ?? 0) + 1;
echo "You've viewed this page {$_SESSION['visits']} times.";- Call
session_start()at the top of every page that uses the session, before any HTML is sent. $_SESSIONis an array that survives between page loads for the same visitor.- Store any normal PHP values in it: numbers, strings and arrays.
- The data lives on the server; the browser only holds a cookie, usually called
PHPSESSID, with the session's ID.
Logging in and out
Sessions are how websites remember that someone has logged in. After checking a username and password, store who they are:
session_regenerate_id(true); // protect against session fixation
$_SESSION['user_id'] = $user['id'];Every protected page then checks for it and sends visitors away if it's missing:
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}To log out, clear the data and destroy the session with $_SESSION = []; followed by session_destroy();. Passwords themselves should never be stored in plain text; use password_hash() when saving and password_verify() when checking.
Cookies
A cookie is set with setcookie() and read on later requests from $_COOKIE:
setcookie('theme', 'dark', [
'expires' => time() + 60 * 60 * 24 * 30, // 30 days
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
$theme = $_COOKIE['theme'] ?? 'light';- Cookies must be set before any output, like
header(). - A newly set cookie only appears in
$_COOKIEon the next request. securesends it only over HTTPS,httponlyhides it from JavaScript, andsamesitelimits it to your own site's requests.- To delete a cookie, set it again with an expiry time in the past.
Sessions or cookies?
| Session | Cookie | |
|---|---|---|
| Where data is stored | On the server | In the visitor's browser |
| Can the visitor read or change it? | No | Yes |
| Typical lifetime | Until the browser closes or a timeout | Until its expiry date |
| Good for | Logins, baskets, form progress | Preferences like theme or language |
Never trust cookie values: visitors can edit them. Anything that matters for security, such as who is logged in, belongs in the session. Many countries also require consent before setting non-essential cookies, so keep cookies to what your site genuinely needs.
PHP Sessions Syntax
Session and cookie syntax
session_start();
$_SESSION['key'] = $value;
$value = $_SESSION['key'] ?? null;
unset($_SESSION['key']);
session_destroy();
setcookie('name', 'value', ['expires' => time() + 3600, 'path' => '/', 'httponly' => true]);
$value = $_COOKIE['name'] ?? 'default';PHP Sessions Summary
- HTTP forgets each request; sessions and cookies let a site remember visitors.
session_start()first, then read and write$_SESSION; the data stays on the server.- Store the user's ID in the session after login; call
session_regenerate_id(true); destroy it on logout. setcookie()stores small values in the browser, read later from$_COOKIE.- Use secure, httponly and samesite options, and never trust cookie contents.
PHP Sessions Examples
Each example shows the code, the output it produces and what each part does.
A shopping basket in the session
The visitor added a pen twice and a notebook once, on three separate page loads.
<?php
session_start();
$_SESSION['basket'] ??= [];
function addToBasket(string $item): void {
$_SESSION['basket'][$item] = ($_SESSION['basket'][$item] ?? 0) + 1;
}
addToBasket('Pen');
addToBasket('Notebook');
addToBasket('Pen');
foreach ($_SESSION['basket'] as $item => $qty) {
echo "$item x $qty\n";
}
echo "Items: " . array_sum($_SESSION['basket']);Pen x 2
Notebook x 1
Items: 3Line-by-line explanation
- Line 3Start with an empty basket the first time.
- Lines 5 to 7The basket is an associative array of item names and quantities.
- Lines 9 to 11In a real shop each call would happen on a different request; the session keeps the basket in between.
- Line 16array_sum adds up all the quantities.
Protecting a members-only page
<?php
// members.php
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
$name = $_SESSION['user_name'] ?? 'member';
?>
<h1>Welcome back, <?= htmlspecialchars($name) ?></h1>
<a href="logout.php">Log out</a><h1>Welcome back, Sam</h1>
<a href="logout.php">Log out</a>Line-by-line explanation
- Lines 5 to 8Visitors who haven't logged in are sent to the login page; exit stops the rest of the page.
- Line 9Values saved at login are available on every later page.
- Line 11Even session data is escaped before printing.
Remembering a theme with a cookie
On the second visit, the browser sends the cookie back.
<?php
$allowed = ['light', 'dark'];
if (isset($_GET['theme']) && in_array($_GET['theme'], $allowed)) {
setcookie('theme', $_GET['theme'], [
'expires' => time() + 60 * 60 * 24 * 365,
'path' => '/',
'samesite' => 'Lax',
]);
$theme = $_GET['theme'];
} else {
$theme = in_array($_COOKIE['theme'] ?? '', $allowed) ? $_COOKIE['theme'] : 'light';
}
echo "<body class=\"theme-$theme\">";<body class="theme-dark">Line-by-line explanation
- Line 3Only accept values from the allowed list.
- Lines 4 to 8Store the choice for a year.
- Line 9The new cookie isn't in $_COOKIE until the next request, so use the chosen value directly.
- Line 11On later visits, read the cookie, but still check it, because visitors can edit cookies.
Common PHP Sessions Mistakes
Output before session_start
<html>
<?php session_start(); ?> <!-- Warning: headers already sent --><?php session_start(); ?>
<html>Trusting a cookie for security
if ($_COOKIE['is_admin'] === 'yes') { showAdminPanel(); }if (($_SESSION['role'] ?? '') === 'admin') { showAdminPanel(); }Anyone can edit their own cookies; session data stays on the server.
Forgetting exit after a redirect
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
}
showSecretData(); // still runsif (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}PHP Sessions in Real Projects
Sessions and cookies on real sites
Online shops keep baskets in sessions, every login system stores the signed-in user in a session, and sites remember language and theme choices with cookies. Frameworks wrap these features in friendlier APIs, but underneath they use exactly these PHP functions, with security options turned on by default.
PHP Sessions FAQ
How long does a PHP session last?
By default the session cookie expires when the browser closes, and the server may delete session data that hasn't been used for session.gc_maxlifetime seconds, 1,440 seconds or 24 minutes by default. Many applications also store a last-activity time in the session and log users out after their own chosen period of inactivity.
Why should I call session_regenerate_id after logging in?
It gives the visitor a new session ID at the moment their privileges change. Without it, an attacker who managed to plant a known session ID in the victim's browser before login, an attack called session fixation, could use that same ID afterwards. Call session_regenerate_id(true) straight after a successful login.
Where does PHP store session data?
By default, in files in the folder set by session.save_path, one file per session. Sites that run on several servers usually store sessions in Redis, Memcached or a database instead, so every server can read the same session.
Can a cookie store an array?
Cookies store text only, and browsers limit each one to about 4 KB. You can store a small array as JSON with json_encode, but remember that visitors can read and edit it. Keep larger or sensitive data in the session or database, and store only an identifier in the cookie.
How do I keep a user logged in after the browser closes?
Use a "remember me" token: generate a long random value, store a hash of it in the database with the user's ID and an expiry date, and set the token in a long-lived, httponly, secure cookie. When it comes back, look up the hash and start a new session. Never store the password or user ID alone in a cookie.
PHP Sessions Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Complete the code so the session can be used.
();
$_SESSION['name'] = 'Sam';
Where is session data stored?
What does this output on the first visit, when no cookie exists yet?
setcookie('lang', 'fr');
echo $_COOKIE['lang'] ?? 'en';
What should you do right after a successful login?
What does the httponly cookie option do?
PHP Sessions Quiz
5 questions to check what you learned.
Why do websites need sessions or cookies?
- To make pages faster
- To store images
- To send emails
- Because HTTP doesn't remember anything between requests
How do you log a user out?
- Clear $_SESSION and call session_destroy()
- Delete their account
- Set $_COOKIE to empty
- Restart the server
What causes "headers already sent"?
- Output, even whitespace, before session_start(), setcookie() or header()
- Too many cookies
- A missing database
- Using $_SESSION twice
Which is better for remembering who is logged in?
- A cookie containing the username
- A hidden form field
- The session, which stores data on the server
- The page URL
Which functions should handle passwords?
- md5() and ==
- password_hash() to store and password_verify() to check
- base64_encode and base64_decode
- Store them in plain text in the session