What Are We Doing in This Post?
In Episode 09 we learned how to receive user input through forms. But there is a problem we have not solved yet.
HTTP is stateless. That means every time your browser sends a request to the server, PHP has absolutely no memory of the previous request. You log in on one page — and on the very next page, PHP has already forgotten who you are.
This is one of the most fundamental challenges of web development. And sessions and cookies are how we solve it.
The Problem — PHP Has No Memory
Real world analogy: Imagine calling a customer support line where every time you are transferred to a new agent, they have zero record of your previous conversation. You have to introduce yourself and explain your entire problem from scratch every single time. That is exactly what HTTP is like by default — completely stateless.
Sessions and cookies are the solution. They are two different mechanisms that let PHP remember information about a user across multiple requests and multiple pages.
What is a Cookie?
A cookie is a small piece of data that the server sends to the browser, and the browser stores it on the user's computer. On every future request to the same website, the browser automatically sends that cookie back to the server.
Real world analogy: Think of a cookie like a stamp you get when you enter a theme park. The staff stamps your hand when you first enter. Every time you go in and out of different areas, the staff checks your stamp instead of asking you to buy a new ticket each time.
Cookies are stored on the user's machine. The user can see them, edit them, or delete them. Never store sensitive data like passwords in cookies.
Setting a cookie in PHP:
<?php
setcookie("username", "Gagan", time() + (86400 * 7));
echo "Cookie has been set.";
?>
setcookie() takes three main arguments: the cookie name, the cookie value, and the expiry time.
time() returns the current Unix timestamp — the number of seconds since January 1, 1970. Adding 86400 * 7 adds seven days worth of seconds. So this cookie expires in 7 days.
Important: setcookie() must be called before any HTML output — before any echo, before any HTML tags. PHP needs to send cookie data in the HTTP headers, and headers must go before any body content.
Reading a cookie:
<?php
if (isset($_COOKIE["username"])) {
echo "Welcome back, " . $_COOKIE["username"];
} else {
echo "No cookie found. This is your first visit.";
}
?>
$_COOKIE is a superglobal just like $_POST and $_GET. PHP automatically populates it with all cookies the browser sent with the current request.
Note: a cookie you just set with setcookie() will not appear in $_COOKIE until the next request. The browser receives it, stores it, and sends it back on the next page load.
Deleting a cookie:
<?php
setcookie("username", "", time() - 3600);
echo "Cookie deleted.";
?>
To delete a cookie, set it again with an expiry time in the past. The browser sees it has expired and removes it.
A Practical Cookie Example — Theme Preference
Let us build something real. A page that remembers the user's preferred theme.
Create theme.php in your phplearning folder:
<?php
if (isset($_POST["theme"])) {
setcookie("theme", $_POST["theme"], time() + (86400 * 30));
$theme = $_POST["theme"];
} elseif (isset($_COOKIE["theme"])) {
$theme = $_COOKIE["theme"];
} else {
$theme = "light";
}
$bg = ($theme == "dark") ? "#1a1a2e" : "#ffffff";
$color = ($theme == "dark") ? "#e2e8f0" : "#1a1a2e";
?>
<!DOCTYPE html>
<html>
<head>
<title>Theme Preference</title>
</head>
<body style="background:<?php echo $bg; ?>; color:<?php echo $color; ?>; padding:40px; font-family:sans-serif;">
<h2>Theme Preference Demo</h2>
<p>Current theme: <strong><?php echo $theme; ?></strong></p>
<p>Close this tab, reopen it, and your theme choice will still be here.</p>
<form method="POST" action="theme.php">
<button name="theme" value="light" type="submit">Light Theme</button>
<button name="theme" value="dark" type="submit">Dark Theme</button>
</form>
</body>
</html>
Visit http://localhost:8080/phplearning/theme.php
Switch between themes. Close the tab. Reopen it. Your choice persists — because it is stored in a cookie on your computer.
What is a Session?
A session is similar to a cookie but with one critical difference: the data is stored on the server, not in the browser.
When a session starts, PHP generates a unique random session ID and sends it to the browser as a cookie. On every future request, the browser sends that session ID back to the server. PHP uses that ID to look up the session data stored on the server side.
Real world analogy: Think of a session like a coat check at a restaurant. When you arrive, the staff takes your coat and gives you a numbered ticket. You carry only the small ticket. Every time you need your coat, you show the ticket and they retrieve it from the back. Your actual belongings stay safely with the restaurant — you only carry an ID that points to them.
The browser only ever holds a session ID — a random string like a3f8b2c9d1e0. The actual session data sits on the server. This makes sessions far more secure than cookies for storing sensitive information.
Starting a session:
<?php
session_start();
?>
session_start() must be the very first thing in your PHP file — before any HTML output, before any echo. It either creates a new session or resumes an existing one based on the session ID cookie the browser sends.
Storing data in a session:
<?php
session_start();
$_SESSION["username"] = "Gagan";
$_SESSION["role"] = "admin";
$_SESSION["user_id"] = 42;
echo "Session data saved.";
?>
$_SESSION is a superglobal array. Whatever you store in it is available on any page of your website as long as the session is active.
Reading session data on another page:
<?php
session_start();
if (isset($_SESSION["username"])) {
echo "Welcome, " . $_SESSION["username"];
echo "<br>Your role is: " . $_SESSION["role"];
} else {
echo "No active session. Please log in.";
}
?>
Every page that needs session data must call session_start() at the top. PHP then loads the session data for that user automatically.
Destroying a session — logout:
<?php
session_start();
$_SESSION = [];
session_destroy();
echo "You have been logged out.";
?>
$_SESSION = [] clears all session variables. session_destroy() removes the session from the server entirely. This is exactly what happens when a user clicks "Log Out" on any website.
A Complete Real World Example — Simple Login System
Let us build a proper multi-page login system using sessions. This will be three files.
File 1 — login.php:
<?php
session_start();
if (isset($_SESSION["username"])) {
header("Location: dashboard.php");
exit();
}
$error = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$username = trim($_POST["username"] ?? "");
$password = trim($_POST["password"] ?? "");
$valid_username = "gagan";
$valid_password = "password123";
if ($username === $valid_username && $password === $valid_password) {
$_SESSION["username"] = $username;
$_SESSION["logged_in"] = true;
header("Location: dashboard.php");
exit();
} else {
$error = "Invalid username or password.";
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body style="font-family:sans-serif; max-width:400px; margin:60px auto; padding:0 16px;">
<h2>Login</h2>
<?php if ($error): ?>
<p style="color:red;"><?php echo $error; ?></p>
<?php endif; ?>
<form method="POST" action="login.php">
<label>Username</label><br>
<input type="text" name="username" style="width:100%; padding:8px; margin:6px 0 14px;" /><br>
<label>Password</label><br>
<input type="password" name="password" style="width:100%; padding:8px; margin:6px 0 14px;" /><br>
<button type="submit" style="background:#6366f1; color:#fff; padding:10px 24px; border:none; border-radius:6px; cursor:pointer;">Login</button>
</form>
</body>
</html>
File 2 — dashboard.php:
<?php
session_start();
if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true) {
header("Location: login.php");
exit();
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Dashboard</title>
</head>
<body style="font-family:sans-serif; max-width:600px; margin:60px auto; padding:0 16px;">
<h2>Welcome to your Dashboard</h2>
<p>Hello, <strong><?php echo htmlspecialchars($_SESSION["username"]); ?></strong>! You are logged in.</p>
<p>This page is protected. Only logged-in users can see it.</p>
<br>
<a href="logout.php">Log Out</a>
</body>
</html>
File 3 — logout.php:
<?php
session_start();
$_SESSION = [];
session_destroy();
header("Location: login.php");
exit();
?>
Visit http://localhost:8080/phplearning/login.php
Try going directly to dashboard.php without logging in — you get redirected to login.php automatically.
Log in with username: gagan and password: password123. You land on the dashboard. Close the tab and reopen dashboard.php — you are still logged in because the session persists.
Click Log Out — session is destroyed and you are sent back to login.
This is the exact flow that every login system in the world follows. Laravel's authentication system does the same thing — just with more features and security layers built on top.
Two things to note from this example.
header("Location: ..."):
This is how PHP redirects a user to a different page. header() sends an HTTP header to the browser. The Location header tells the browser to navigate to a new URL. exit() after header() is critical — without it, PHP continues executing the rest of the code even after redirecting.
The session guard pattern:
<?php
if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true) {
header("Location: login.php");
exit();
}
?>
This block at the top of any protected page is called a session guard. It checks if the user is logged in and immediately redirects them if they are not. You will put this at the top of every page that requires authentication. In Laravel, middleware does this automatically — but understanding the raw PHP version makes Laravel's middleware make complete sense.
Sessions vs Cookies — When to Use Which
Use sessions when storing sensitive data — user ID, role, login status. The data stays on the server. The browser only holds a random ID. Expires when the browser is closed by default.
Use cookies when storing non-sensitive preferences — theme choice, language preference, recently viewed items. The data lives in the browser. Can persist for days, weeks, or months. User can see and delete them.
Never store passwords, payment details, or any sensitive data in cookies. Always use sessions for anything security-related.
What Did We Learn in This Post?
HTTP is stateless — PHP has no memory between requests by default. Sessions and cookies solve this.
Cookies store data in the browser. setcookie() creates them. $_COOKIE reads them. They can persist for days or weeks. Never store sensitive data in cookies.
Sessions store data on the server. session_start() begins or resumes a session. $_SESSION stores and reads session data. session_destroy() ends a session.
header("Location: url") redirects the user to another page. Always call exit() immediately after.
A session guard at the top of protected pages checks login status and redirects unauthenticated users — this is the foundation of every authentication system.
What is Coming in Episode 11?
Now that we understand how to receive user input and remember user state, it is time to start working with databases.
Episode 11 covers MySQL and PHP together — connecting PHP to a MySQL database, creating tables, inserting data, fetching records, and displaying them on a webpage. This is the episode where everything starts feeling like a real application.
See you in the next one.
Next Episode: PHP and MySQL — Connecting to a Database and Working With Real Data
This is Episode 10 of the PHP and Laravel — Zero to Hero series.
No comments:
Post a Comment