Skip to content

PHP Cookies

Cookies are a mechanism for storing small pieces of data on the client-side (user’s browser) and are often used to identify users or store preferences across sessions.

A cookie is a small file created by the server and stored on the user’s computer by their web browser. When the user requests a page from the same server, the browser sends the relevant cookie(s) back with the request. PHP provides functions to create, retrieve, modify, and delete cookie values.

Common uses include session management (though PHP sessions are often preferred), personalization (like themes), and tracking user behavior (less common now due to privacy concerns).

Cookies are created using the setcookie() function. It’s crucial to call this function before any HTML output is sent to the browser (before <html>, <?php echo ...; ?>, or even whitespace).

`setcookie(name, value, expires_or_options, path, domain, secure, httponly)`<br>
Or using the modern options array (PHP 7.3+):<br>
`setcookie(name, value, ['expires' => expiration_timestamp, 'path' => '/', 'domain' => 'example.com', 'secure' => true, 'httponly' => true, 'samesite' => 'Lax'])`
  • name: The name of the cookie (required).
  • value: The value to store. Automatically URL-encoded.
  • expires_or_options: (Optional) Expiration timestamp (Unix timestamp) or an options array (recommended). Setting an expiration time in the past deletes the cookie.
  • path: (Optional) The path on the server where the cookie will be available. ’/’ means the entire domain.
  • domain: (Optional) The domain the cookie is valid for (e.g., ‘.example.com’ for subdomains).
  • secure: (Optional, boolean) If true, only sends the cookie over HTTPS connections. Strongly recommended.
  • httponly: (Optional, boolean) If true, the cookie cannot be accessed via client-side scripts (like JavaScript), mitigating XSS attacks. Strongly recommended.
  • samesite: (Optional, string) Controls cross-site request behavior (‘None’, ‘Lax’, ‘Strict’). Helps mitigate CSRF attacks. ‘Lax’ is often a good default.

This example creates a cookie named ‘user’ with the value ‘John Doe’. It expires after 30 days, is available site-wide, and includes important security flags.

We then retrieve the value using the $_COOKIE superglobal array and use isset() to check if it exists.

<?php
$cookie_name = "user";
$cookie_value = "John Doe";
$expiry = time() + (86400 * 30); // 86400 = 1 day
$path = "/";
$domain = ""; // Current domain
$secure = true; // Only send over HTTPS
$httponly = true; // Prevent JavaScript access
// Modern syntax using options array (PHP 7.3+)
setcookie($cookie_name, $cookie_value, [
'expires' => $expiry,
'path' => $path,
// 'domain' => $domain, // Often best left empty or set explicitly
'secure' => $secure,
'httponly' => $httponly,
'samesite' => 'Lax' // Recommended default
]);
/* // Older syntax (still works)
setcookie($cookie_name, $cookie_value, $expiry, $path, $domain, $secure, $httponly);
*/
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>PHP Cookie Example</title>
</head>
<body>
<h1>Cookie Status</h1>
<?php
if (!isset($_COOKIE[$cookie_name])) {
echo "Cookie named '" . htmlspecialchars($cookie_name) . "' is not set!";
} else {
echo "Cookie '" . htmlspecialchars($cookie_name) . "' is set!<br>";
// Always sanitize output from cookies (or any user input)
echo "Value is: " . htmlspecialchars($_COOKIE[$cookie_name]);
}
?>
<p>**Note:** Cookies might not be immediately available in $_COOKIE on the same page load they are set. They are sent by the browser on subsequent requests.</p>
</body>
</html>
Important: The setcookie() function must be called before any output is sent to the browser (HTML, whitespace, echo/print statements). Failure to do so will result in a “Headers already sent” warning and the cookie will not be set.

Note: The cookie value is automatically URL-encoded when sent and decoded when received. Use setrawcookie() if you need to send a value without URL encoding (rarely needed).

To modify a cookie, simply call setcookie() again with the same name but a new value and/or expiration time. Ensure you use the same path, domain, secure, and httponly settings as the original cookie.

<?php
$cookie_name = "user";
$new_value = "Alex Porter";
$expiry = time() + (86400 * 30);
$path = "/";
$secure = true;
$httponly = true;
// Set the cookie again with the new value
setcookie($cookie_name, $new_value, [
'expires' => $expiry,
'path' => $path,
'secure' => $secure,
'httponly' => $httponly,
'samesite' => 'Lax'
]);
?>
<!DOCTYPE html>
<html lang="en">
<head><title>Modify Cookie</title></head>
<body>
<h1>Modifying Cookie</h1>
<p>Cookie '<?php echo htmlspecialchars($cookie_name); ?>' value is being updated.</p>
<?php
if (isset($_COOKIE[$cookie_name])) {
echo "<p>Current value (from previous request): " . htmlspecialchars($_COOKIE[$cookie_name]) . "</p>";
}
echo "<p>New value set to: " . htmlspecialchars($new_value) . " (will be visible on next page load)</p>";
?>
</body>
</html>

To delete a cookie, call setcookie() with the cookie’s name and an expiration date in the past. Again, match the path, domain, etc., for the deletion to work correctly.

<?php
$cookie_name = "user";
// Set the expiration date to one hour ago
setcookie($cookie_name, "", time() - 3600, "/", "", true, true); // Matching path, secure, httponly
// Alternatively, using the options array:
/*
setcookie($cookie_name, '', [
'expires' => time() - 3600,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax'
]);
*/
?>
<!DOCTYPE html>
<html lang="en">
<head><title>Delete Cookie</title></head>
<body>
<h1>Deleting Cookie</h1>
<p>Cookie '<?php echo htmlspecialchars($cookie_name); ?>' has been deleted (or attempted deletion).</p>
<?php
// Unset the variable in the current script for immediate effect (doesn't delete browser cookie)
unset($_COOKIE[$cookie_name]);
if (!isset($_COOKIE[$cookie_name])) {
echo "<p>Cookie variable is now unset in this script execution.</p>";
} else {
echo "<p>Cookie variable still exists in this script execution (unexpected).</p>";
}
?>
<p>Refresh the page to confirm the browser no longer sends the cookie.</p>
</body>
</html>

You can check if cookies are enabled by attempting to set a test cookie and then checking if it exists on a subsequent request. A common technique involves setting a cookie and immediately redirecting or providing a link to another page that checks for the cookie.

Simple check (less reliable, might show cookies from previous visits):

<?php
// Attempt to set a test cookie
setcookie("test_cookie", "test_value", time() + 3600, '/', '', true, true);
?>
<!DOCTYPE html>
<html lang="en">
<head><title>Check Cookies Enabled</title></head>
<body>
<h1>Checking Cookie Support</h1>
<?php
// Check if $_COOKIE is populated. This is a basic check.
// A more reliable check involves setting a cookie and checking on the *next* page load.
if (count($_COOKIE) > 0) {
echo "<p>Cookies appear to be enabled (found existing or test cookie).</p>";
} else {
// This might trigger if it's the very first visit and the test cookie hasn't registered yet.
echo "<p>Cookies might be disabled, or this is the first hit.</p>";
}
?>
<p><a href="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>">Refresh page</a> to see if the test cookie is detected.</p>
</body>
</html>

For managing user sessions or more complex data persistence, PHP Sessions ($_SESSION) are generally preferred over raw cookies. Sessions often use cookies internally but handle the storage and retrieval more securely and abstractly. For stateless authentication, JSON Web Tokens (JWT) stored in cookies or local storage are also popular.