PHP Sessions and Cookies

Remember information between page loads with sessions and cookies, build a simple login and keep both secure.

Lesson 12 of 86Intermediate17 min read

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
<?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.
  • $_SESSION is 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:

PHP
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:

PHP
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:

PHP
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 $_COOKIE on the next request.
  • secure sends it only over HTTPS, httponly hides it from JavaScript, and samesite limits it to your own site's requests.
  • To delete a cookie, set it again with an expiry time in the past.

Sessions or cookies?

SessionCookie
Where data is storedOn the serverIn the visitor's browser
Can the visitor read or change it?NoYes
Typical lifetimeUntil the browser closes or a timeoutUntil its expiry date
Good forLogins, baskets, form progressPreferences 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.

Example 1

A shopping basket in the session

The visitor added a pen twice and a notebook once, on three separate page loads.

PHP
<?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']);
Output
Pen x 2
Notebook x 1
Items: 3
Line-by-line explanation
  1. Line 3Start with an empty basket the first time.
  2. Lines 5 to 7The basket is an associative array of item names and quantities.
  3. Lines 9 to 11In a real shop each call would happen on a different request; the session keeps the basket in between.
  4. Line 16array_sum adds up all the quantities.
Example 2

Protecting a members-only page

PHP
<?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>
Output
<h1>Welcome back, Sam</h1>
<a href="logout.php">Log out</a>
Line-by-line explanation
  1. Lines 5 to 8Visitors who haven't logged in are sent to the login page; exit stops the rest of the page.
  2. Line 9Values saved at login are available on every later page.
  3. Line 11Even session data is escaped before printing.
Example 3

Remembering a theme with a cookie

On the second visit, the browser sends the cookie back.

PHP
<?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\">";
Output
<body class="theme-dark">
Line-by-line explanation
  1. Line 3Only accept values from the allowed list.
  2. Lines 4 to 8Store the choice for a year.
  3. Line 9The new cookie isn't in $_COOKIE until the next request, so use the chosen value directly.
  4. Line 11On later visits, read the cookie, but still check it, because visitors can edit cookies.

Common PHP Sessions Mistakes

Output before session_start

Don't
<html>
<?php session_start(); ?>   <!-- Warning: headers already sent -->
Do
<?php session_start(); ?>
<html>

Trusting a cookie for security

Don't
if ($_COOKIE['is_admin'] === 'yes') { showAdminPanel(); }
Do
if (($_SESSION['role'] ?? '') === 'admin') { showAdminPanel(); }

Anyone can edit their own cookies; session data stays on the server.

Forgetting exit after a redirect

Don't
if (!isset($_SESSION['user_id'])) {
    header('Location: login.php');
}
showSecretData();     // still runs
Do
if (!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.

Fill in the blankseasy

Complete the code so the session can be used.

();
$_SESSION['name'] = 'Sam';
Multiple choiceeasy

Where is session data stored?

Predict the outputmedium

What does this output on the first visit, when no cookie exists yet?

setcookie('lang', 'fr');
echo $_COOKIE['lang'] ?? 'en';
Multiple choicemedium

What should you do right after a successful login?

Multiple choicehard

What does the httponly cookie option do?

PHP Sessions Quiz

5 questions to check what you learned.

  1. 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
  2. How do you log a user out?

    • Clear $_SESSION and call session_destroy()
    • Delete their account
    • Set $_COOKIE to empty
    • Restart the server
  3. What causes "headers already sent"?

    • Output, even whitespace, before session_start(), setcookie() or header()
    • Too many cookies
    • A missing database
    • Using $_SESSION twice
  4. 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
  5. 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