PHP Fundamentals

Sessions & Cookies

13 min Lesson 20 of 45

Sessions & Cookies

Sessions and cookies are essential for maintaining state and user data across multiple page requests. They enable features like login systems, shopping carts, user preferences, and more.

What Are Sessions?

Sessions allow you to store user data on the server for the duration of a user's visit. Each user gets a unique session ID stored in a cookie.

Key Difference:
  • Sessions: Data stored on server, more secure, expires when browser closes
  • Cookies: Data stored in browser, less secure, can persist longer

Working with Sessions

Starting a Session

<?php // ALWAYS start session at the top of the file, before any output session_start(); // Now you can use $_SESSION $_SESSION['username'] = 'John'; $_SESSION['user_id'] = 123; $_SESSION['role'] = 'admin'; echo "Session started!"; ?>
Important: Call session_start() before ANY output (HTML, echo, etc.). Otherwise you'll get "headers already sent" error.

Reading Session Data

<?php session_start(); // Check if session variable exists if (isset($_SESSION['username'])) { echo "Welcome back, " . $_SESSION['username']; } else { echo "Please log in"; } // Get session variable with default value $role = $_SESSION['role'] ?? 'guest'; echo "Your role: $role"; ?>

Destroying Sessions

<?php session_start(); // Remove specific session variable unset($_SESSION['username']); // Remove all session variables session_unset(); // Destroy the session completely session_destroy(); echo "You have been logged out"; ?>

Complete Login System Example

<?php // login.php session_start(); $error = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $username = trim($_POST['username']); $password = $_POST['password']; // In real application, check against database // This is just for demonstration if ($username === 'admin' && $password === 'password123') { // Set session variables $_SESSION['user_id'] = 1; $_SESSION['username'] = $username; $_SESSION['role'] = 'admin'; $_SESSION['logged_in'] = true; $_SESSION['login_time'] = time(); // Redirect to dashboard header('Location: dashboard.php'); exit; } else { $error = "Invalid username or password"; } } ?> <!DOCTYPE html> <html> <head> <title>Login</title> <style> .error { color: red; } .form-group { margin-bottom: 15px; } </style> </head> <body> <h1>Login</h1> <?php if ($error): ?> <div class="error"><?php echo $error; ?></div> <?php endif; ?> <form method="post"> <div class="form-group"> <label for="username">Username:</label> <input type="text" id="username" name="username" required> </div> <div class="form-group"> <label for="password">Password:</label> <input type="password" id="password" name="password" required> </div> <button type="submit">Login</button> </form> </body> </html>
<?php // dashboard.php session_start(); // Check if user is logged in if (!isset($_SESSION['logged_in']) || !$_SESSION['logged_in']) { header('Location: login.php'); exit; } $username = $_SESSION['username']; $role = $_SESSION['role']; $login_time = date('Y-m-d H:i:s', $_SESSION['login_time']); ?> <!DOCTYPE html> <html> <head> <title>Dashboard</title> </head> <body> <h1>Dashboard</h1> <p>Welcome, <?php echo htmlspecialchars($username); ?>!</p> <p>Role: <?php echo htmlspecialchars($role); ?></p> <p>Logged in at: <?php echo $login_time; ?></p> <a href="logout.php">Logout</a> </body> </html>
<?php // logout.php session_start(); // Clear session data $_SESSION = []; // Destroy session cookie if (isset($_COOKIE[session_name()])) { setcookie(session_name(), '', time() - 3600, '/'); } // Destroy session session_destroy(); // Redirect to login header('Location: login.php'); exit; ?>

Session Security

<?php session_start(); // Regenerate session ID to prevent session fixation session_regenerate_id(true); // Set session timeout (30 minutes) $timeout = 1800; // seconds if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity']) > $timeout) { session_unset(); session_destroy(); header('Location: login.php?timeout=1'); exit; } $_SESSION['last_activity'] = time(); // Store user IP to prevent session hijacking if (!isset($_SESSION['user_ip'])) { $_SESSION['user_ip'] = $_SERVER['REMOTE_ADDR']; } else { if ($_SESSION['user_ip'] !== $_SERVER['REMOTE_ADDR']) { session_unset(); session_destroy(); die('Session hijacking detected'); } } ?>

Working with Cookies

Setting Cookies

<?php // Basic cookie (expires in 1 hour) setcookie('username', 'John', time() + 3600); // Cookie with path and domain setcookie('theme', 'dark', time() + (86400 * 30), '/'); // 30 days // Secure cookie (HTTPS only) setcookie('token', 'abc123', time() + 3600, '/', '', true, true); // Parameters: name, value, expire, path, domain, secure, httponly // Cookie that expires when browser closes setcookie('temp_data', 'value', 0); echo "Cookies set!"; ?>
Cookie Parameters:
  • name: Cookie name
  • value: Cookie value
  • expire: Expiration timestamp (0 = session cookie)
  • path: Path where cookie is available ('/' = entire domain)
  • domain: Domain where cookie is available
  • secure: Only send over HTTPS
  • httponly: Not accessible via JavaScript (XSS protection)

Reading Cookies

<?php // Check if cookie exists if (isset($_COOKIE['username'])) { echo "Welcome back, " . $_COOKIE['username']; } else { echo "First time visitor"; } // Get cookie with default value $theme = $_COOKIE['theme'] ?? 'light'; // Display all cookies echo '<pre>'; print_r($_COOKIE); echo '</pre>'; ?>

Deleting Cookies

<?php // Delete cookie by setting expiration to past setcookie('username', '', time() - 3600); // Or use 1 as expiration setcookie('theme', '', 1); echo "Cookies deleted"; ?>

Remember Me Functionality

<?php // login.php with "Remember Me" session_start(); if ($_SERVER['REQUEST_METHOD'] === 'POST') { $username = $_POST['username']; $password = $_POST['password']; $remember = isset($_POST['remember']); // Validate credentials (simplified) if ($username === 'admin' && $password === 'password123') { // Set session $_SESSION['user_id'] = 1; $_SESSION['username'] = $username; // If "Remember Me" is checked if ($remember) { // Generate secure token $token = bin2hex(random_bytes(32)); // Store token in database with user_id // $db->query("INSERT INTO remember_tokens ..."); // Set cookie with token (30 days) setcookie('remember_token', $token, time() + (86400 * 30), '/', '', true, true); } header('Location: dashboard.php'); exit; } } ?> <form method="post"> <input type="text" name="username" required> <input type="password" name="password" required> <label> <input type="checkbox" name="remember" value="1"> Remember Me </label> <button type="submit">Login</button> </form>
<?php // Auto-login check (top of every protected page) session_start(); if (!isset($_SESSION['user_id']) && isset($_COOKIE['remember_token'])) { $token = $_COOKIE['remember_token']; // Check token in database // $user = $db->query("SELECT user_id FROM remember_tokens WHERE token = ?"); // If valid, log in user // $_SESSION['user_id'] = $user['user_id']; } ?>

Shopping Cart Example

<?php // add_to_cart.php session_start(); // Initialize cart if not exists if (!isset($_SESSION['cart'])) { $_SESSION['cart'] = []; } // Add item to cart if (isset($_POST['product_id'])) { $product_id = intval($_POST['product_id']); $quantity = intval($_POST['quantity']) ?: 1; // If product already in cart, increase quantity if (isset($_SESSION['cart'][$product_id])) { $_SESSION['cart'][$product_id] += $quantity; } else { $_SESSION['cart'][$product_id] = $quantity; } echo "Added to cart!"; } ?>
<?php // view_cart.php session_start(); $cart = $_SESSION['cart'] ?? []; if (empty($cart)) { echo "Your cart is empty"; } else { echo "<h2>Your Cart</h2>"; echo "<table>"; echo "<tr><th>Product ID</th><th>Quantity</th><th>Action</th></tr>"; foreach ($cart as $product_id => $quantity) { echo "<tr>"; echo "<td>$product_id</td>"; echo "<td>$quantity</td>"; echo "<td><a href='remove_from_cart.php?id=$product_id'>Remove</a></td>"; echo "</tr>"; } echo "</table>"; echo "<p>Total items: " . array_sum($cart) . "</p>"; } ?>
<?php // remove_from_cart.php session_start(); if (isset($_GET['id'])) { $product_id = intval($_GET['id']); unset($_SESSION['cart'][$product_id]); } header('Location: view_cart.php'); exit; ?>

Session Configuration (php.ini)

; Important session settings in php.ini session.cookie_httponly = 1 ; Prevent JavaScript access session.cookie_secure = 1 ; HTTPS only session.use_strict_mode = 1 ; Reject uninitialized session IDs session.cookie_samesite = Strict ; CSRF protection session.gc_maxlifetime = 1800 ; Session lifetime (30 minutes) session.cookie_lifetime = 0 ; Cookie expires when browser closes

Session vs Cookies Comparison

Feature Sessions Cookies
Storage Location Server Client (Browser)
Security More secure Less secure (can be modified)
Size Limit Server dependent (usually large) 4KB per cookie
Expiration Browser close or timeout Set by developer (days, months, years)
Data Types Any PHP data type Strings only
Best For Sensitive data, login state Preferences, tracking, remember me

Best Practices

Security Best Practices:
  • Always use session_regenerate_id() after login
  • Set httponly flag on cookies
  • Use HTTPS and set secure flag
  • Implement session timeout
  • Never store sensitive data in cookies
  • Validate session data on each request
  • Check for session hijacking
  • Use CSRF tokens for forms
  • Destroy sessions on logout
  • Set appropriate session garbage collection

Practice Exercise

Task: Create a complete user authentication system with:

  1. Login page with username/password
  2. Registration page
  3. Protected dashboard page
  4. Logout functionality
  5. "Remember Me" checkbox (30-day cookie)
  6. Session timeout after 15 minutes of inactivity
  7. Display login time on dashboard
  8. User preferences page (store theme preference in cookie)

Security Requirements:

  • Regenerate session ID on login
  • Hash passwords (use password_hash())
  • Protect against session hijacking
  • Use secure and httponly cookies
  • Redirect non-logged-in users to login page

Summary

In this lesson, you learned:

  • What sessions and cookies are and when to use each
  • Starting and managing sessions with session_start()
  • Storing and retrieving session data
  • Destroying sessions properly
  • Creating a complete login/logout system
  • Session security (timeout, regeneration, hijacking prevention)
  • Setting, reading, and deleting cookies
  • Implementing "Remember Me" functionality
  • Building a shopping cart with sessions
  • Session vs cookies comparison
  • Security best practices

Congratulations! You've completed Module 4: Superglobals & Forms. You now have the skills to build interactive, stateful PHP applications with forms, file uploads, and user authentication!