PHP Fundamentals
Sessions & Cookies
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
httponlyflag on cookies - Use HTTPS and set
secureflag - 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:
- Login page with username/password
- Registration page
- Protected dashboard page
- Logout functionality
- "Remember Me" checkbox (30-day cookie)
- Session timeout after 15 minutes of inactivity
- Display login time on dashboard
- 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!