PHP: Cookies in PHP
HTTP is stateless — the server doesn't remember who you are between requests. Cookies solve this: the server gives your browser a small sticky note, and the next time your browser comes back with it, the server says, "Oh, it's you!"
1. What Is a Cookie?
A cookie is a small piece of data (≤ 4KB) that the server asks the browser to store on the user's computer. The browser automatically sends it back on every subsequent request.
TEXT
📖 Display only
First visit:
Browser → Server: Hello!
Server → Browser: Here's a cookie: user=John
Next visit:
Browser → Server: Hello, here's my cookie: user=John
Server: Ah, John — your cart is still here!
PHP
<?php
// Create a cookie
setcookie("username", "John", time() + 3600, "/");
// Read a cookie
echo $_COOKIE['username'] ?? 'Guest'; // John (persists after refresh)
?>
2. setcookie() Parameters
PHP
setcookie(
string $name, // Cookie name
string $value = "", // Cookie value
int $expires = 0, // Expiry (Unix timestamp; 0 = expires when browser closes)
string $path = "", // Path scope ("/" = entire site)
string $domain = "", // Domain scope
bool $secure = false, // HTTPS only
bool $httponly = false // Inaccessible to JavaScript
);
PHP
<?php
// Simplest cookie (deleted when the browser closes)
setcookie("visit_count", "1");
// Cookie that expires in 1 hour
setcookie("username", "John", time() + 3600, "/");
// Cookie that expires in 7 days
setcookie("remember_token", "abc123", time() + 86400 * 7, "/");
// Secure cookie (HTTPS only, JS can't read it)
setcookie("session_id", "xyz789", [
'expires' => time() + 3600,
'path' => '/',
'secure' => true, // HTTPS only
'httponly' => true, // Blocks XSS-based theft
'samesite' => 'Lax' // Mitigates CSRF
]);
?>
💡 Tip: PHP 7.3+ recommends the array-style
setcookie signature — the named keys make it much harder to mix up parameter order.
3. Reading Cookies: $_COOKIE
PHP
<?php
$username = $_COOKIE['username'] ?? 'Guest';
echo "Welcome, {$username}!";
// $_COOKIE is a superglobal associative array
print_r($_COOKIE);
// Array ( [username] => John [visit_count] => 5 )
?>
▶ Example: Visit Counter
PHP
<?php
// First visit
if (!isset($_COOKIE['visit_count'])) {
setcookie('visit_count', 1, time() + 86400 * 30, "/");
echo "Welcome — this is your first visit!";
} else {
$count = (int)$_COOKIE['visit_count'] + 1;
setcookie('visit_count', $count, time() + 86400 * 30, "/");
echo "This is visit #{$count}!";
}
?>
Output:
TEXT
📖 Display only
Output displayed
4. Deleting Cookies
There's no dedicated "delete cookie" function — you delete a cookie by setting its expiry in the past:
PHP
<?php
// Delete a cookie
setcookie("username", "", time() - 3600, "/");
// Expiry in the past → browser discards it
// unset only removes $_COOKIE from the current request — the browser still has the cookie
unset($_COOKIE['username']);
// This only affects the current script; after a refresh, the cookie is back
?>
🔥 Common Mistake:
setcookie("name", "", time() - 3600) is what actually removes the cookie from the browser. unset($_COOKIE['name']) only clears the variable for the current request.
5. Cookie Security Attributes
| Attribute | Purpose | Recommended |
|---|---|---|
httponly |
JavaScript can't read the cookie (prevents XSS theft) | ✅ Always enable |
secure |
Only transmitted over HTTPS | ✅ Enable in production |
samesite |
Only sent on same-site requests (mitigates CSRF) | Lax or Strict |
path |
Limits the cookie to a specific path | "/" for site-wide |
PHP
<?php
// Secure cookie template
setcookie("user_token", $token, [
'expires' => time() + 86400 * 30,
'path' => '/',
'secure' => isset($_SERVER['HTTPS']),
'httponly' => true,
'samesite' => 'Lax'
]);
?>
6. Real-World Cookie Examples
▶ Example: Remember Me
Output:
TEXT
📖 Display only
<h3>Welcome back, {Alice}!</h3>
PHP
<?php
// remember.php
$savedName = $_COOKIE['saved_username'] ?? '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username'] ?? '');
$remember = isset($_POST['remember']);
if ($remember) {
// "Remember me" — store for 30 days
setcookie('saved_username', $username, time() + 86400 * 30, '/');
} else {
// Don't remember — delete the cookie
setcookie('saved_username', '', time() - 3600, '/');
}
echo "<h3>Welcome back, {$username}!</h3>";
}
?>
<form method="POST">
<input type="text" name="username"
value="<?= htmlspecialchars($savedName) ?>"
placeholder="Enter your username">
<label>
<input type="checkbox" name="remember"> Remember me
</label>
<button type="submit">Log In</button>
</form>
Output:
TEXT
📖 Display only
Welcome back, John!
▶ Example: Theme Switcher
Output:
TEXT
📖 Display only
value
value
PHP
<?php
// theme.php
$theme = $_COOKIE['theme'] ?? 'light';
if (isset($_GET['theme'])) {
$theme = $_GET['theme'] === 'dark' ? 'dark' : 'light';
setcookie('theme', $theme, time() + 86400 * 365, '/');
}
?>
<!DOCTYPE html>
<html>
<head>
<style>
body.dark { background: #222; color: #eee; }
body.light { background: #fff; color: #333; }
</style>
</head>
<body class="<?= $theme ?>">
<h2>Current theme: <?= $theme === 'dark' ? 'Dark' : 'Light' ?></h2>
<a href="?theme=dark">Dark Mode</a> |
<a href="?theme=light">Light Mode</a>
</body>
</html>
Output:
TEXT
📖 Display only
Output displayed
7. Cookie Limitations
| Limit | Value |
|---|---|
| Per-cookie size | ≤ 4096 bytes (4KB) |
| Cookies per domain | ~20–50 (varies by browser) |
| Total cookie payload | ~8KB across all cookies |
| Security | Stored in plain text; users can view and modify |
| Transmission | Sent on every HTTP request automatically |
💡 Tip: Cookies are ideal for small, non-sensitive data (remembering a username, theme preference). For larger or sensitive data, use Sessions (next lesson). For long-term persistence, use a database.
❓ FAQ
Q What's the difference between a cookie and a session?
A Cookies live in the browser; sessions live on the server. Cookies are size-limited and user-modifiable; sessions are more secure but consume server resources. Use sessions for login state; use cookies for "remember me" and preferences.
Q Can users tamper with cookies?
A Yes! Cookies live on the user's machine, so users can modify them freely. Never store sensitive data like passwords in a cookie without encryption. At minimum, use
httponly to stop JavaScript from reading them.📖 Summary
- Cookies are browser-side key-value storage sent automatically with every request
setcookie(name, value, expire, path)creates a cookie- Set the expiry to a past timestamp to delete a cookie
$_COOKIEholds the cookies sent with the current request (newly set cookies require a refresh)httponly(blocks JS),secure(HTTPS only), andsamesite(CSRF protection) are essential security flags- Cookies are limited to 4KB, user-modifiable, and best suited for small, non-sensitive data
📝 Exercises
- Implement a "Remember Me" feature: a login form with a checkbox that, when checked, auto-fills the username field on the next visit.
- Build a theme switcher: let users toggle between light and dark mode on a page, persist the choice in a cookie, and apply it on subsequent visits.
- Create a "Recently Viewed" feature: use a cookie to store the IDs of the last 5 articles a user viewed (store as a comma-separated string).