$_COOKIE

Yo Yogesh.M Updated 29 Oct 2026
7 min read

What Are Cookies?

In simple terms: A cookie is a small piece of text that a website asks the browser to store. On every later request to that website, the browser sends the cookie back. This lets a site "remember" things between page visits — a preferred language, a theme, or which user is logged in. Technically: A server sets a cookie with a Set-Cookie HTTP response header. The browser stores it and includes it in the Cookie request header of subsequent matching requests. PHP parses that header into the $_COOKIE superglobal. Cookies are set with setcookie().

Why Cookies Exist

HTTP is stateless: each request is independent, and the server does not automatically know that two requests came from the same visitor. Cookies add a small amount of state on the client side. Sessions (see $_SESSION) build on cookies: the browser stores only a session ID cookie, and the actual data stays on the server.


Request 1:  Browser ──GET /settings.php──────────────────────────► Server
            Browser ◄──Set-Cookie: theme=dark; Max-Age=31536000── Server   (setcookie)
Request 2:  Browser ──GET /index.php  Cookie: theme=dark─────────► Server
                                       $_COOKIE['theme'] === 'dark'

Important: A cookie set with setcookie() is not available in $_COOKIE during the same request. $_COOKIE reflects what the browser sent with the current request; the new cookie arrives with the next request.


Syntax (PHP 7.3+)

setcookie(string $name, string $value = "", array $options = []): bool
OptionMeaningRecommended
expiresUnix timestamp when the cookie expires; 0 = session cookie (deleted when the browser closes)Set explicitly
pathURL path where the cookie is sent'/'
domainDomain (and subdomains) where the cookie is sentUsually leave empty (current host only)
secureSend only over HTTPStrue in production
httponlyHide from JavaScript (document.cookie)true unless JS must read it
samesiteLax, Strict, or None — controls sending with cross-site requests'Lax'

Example

<?php
// settings.php — must run before any output is sent
setcookie('theme', 'dark', [
    'expires' => time() + 60 * 60 * 24 * 365,   // one year
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);
echo "Theme saved. It will be applied on your next page view.";

Response Header Sent to the Browser (date depends on the current time)

Set-Cookie: theme=dark; expires=Mon, 11 Oct 2027 18:00:00 GMT; Max-Age=31536000; path=/; secure; HttpOnly; SameSite=Lax

Why These Options

  • secure prevents the cookie from travelling over unencrypted HTTP, where it could be intercepted. (On http://localhost during development, browsers may ignore secure cookies — set it based on the environment.)
  • httponly stops JavaScript from reading the cookie, which limits the damage of an XSS vulnerability.
  • samesite: Lax prevents the cookie from being sent with most cross-site requests (such as form posts from other sites), which helps against CSRF. Strict is stricter; None (which requires secure) is needed only for genuinely cross-site use, such as embedded widgets.

Reading Cookies

<?php
// Request header: Cookie: theme=dark; lang=ta
$allowedThemes = ['light', 'dark'];
$theme = $_COOKIE['theme'] ?? 'light';
if (!in_array($theme, $allowedThemes, true)) {
    $theme = 'light';
}
$language = $_COOKIE['lang'] ?? 'en';
echo "Theme: $theme, language: $language\n";

Output

Theme: dark, language: ta

Cookies are user input: the user (or an attacker) can edit, delete, or invent any cookie. Read them with defaults and validate them exactly like $_GET and $_POST data.


Headers Must Be Sent Before Output

Cookies travel in HTTP headers, and headers are sent before the page content. Once any output has been sent — even a space or a blank line before <?php — it is too late:

<html>
<?php
setcookie('theme', 'dark');

Result

PHP Warning:  Cannot modify header information - headers already sent by (output started at /path/settings.php:1) in /path/settings.php on line 3

Fix: Call setcookie() before printing anything — typically at the top of the script or in a controller, before templates are rendered. The warning message tells you exactly where output started. A common hidden cause is whitespace after a closing ?> in an included file, which is why pure PHP files should omit the closing tag.


There is no "delete" function. Instead, set the same cookie again with an expiry date in the past:

<?php
setcookie('theme', '', [
    'expires' => time() - 3600,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);
unset($_COOKIE['theme']);   // also remove it from the current request's data

The path and domain must match the values used when the cookie was set; otherwise the browser treats it as a different cookie and keeps the original.


Storing Structured Data

Cookie values are strings. To store a small list or settings object, encode it as JSON:

<?php
function addRecentlyViewed(array $ids, int $productId, int $max = 5): array
{
    $ids = array_values(array_unique([$productId, ...$ids]));
    return array_slice($ids, 0, $max);
}
$recent = [];
foreach ([12, 7, 12, 3, 9, 4, 15] as $viewedProduct) {
    $recent = addRecentlyViewed($recent, $viewedProduct);
}
echo json_encode($recent) . "\n";
// In the real page:
// setcookie('recent', json_encode($recent), ['expires' => time() + 2592000, 'path' => '/', 'httponly' => true, 'samesite' => 'Lax']);

Output

[15,4,9,3,12]

How It Works

  1. Each viewed product is placed at the front of the list; array_unique() removes an earlier occurrence, so viewing product 12 again moves it to the front instead of duplicating it.
  2. array_slice() keeps only the five most recent IDs, so the cookie stays small. Product 7 dropped off the end.
  3. The list is stored as JSON in the cookie.

Reading It Back Safely

<?php
// Request header: Cookie: recent=%5B15%2C4%2C9%2C3%2C12%5D
$decoded = json_decode($_COOKIE['recent'] ?? '[]', true);
$recent = is_array($decoded)
    ? array_values(array_filter($decoded, fn($id): bool => is_int($id) && $id > 0))
    : [];
echo implode(', ', $recent) . "\n";

Output

15, 4, 9, 3, 12

setcookie() URL-encodes the value, and PHP decodes it automatically when filling $_COOKIE. Because the cookie might have been edited, the decoded data is checked: it must be an array of positive integers. Never pass cookie contents to unserialize() — it can be exploited to create arbitrary objects.


Protecting Cookies From Tampering

Users can change cookie values freely. If a cookie's value must not be altered, sign it with a secret key using HMAC, and verify the signature when reading:

<?php
const COOKIE_SECRET = 'replace-with-a-long-random-secret-from-configuration';
function signValue(string $value): string
{
    return $value . '.' . hash_hmac('sha256', $value, COOKIE_SECRET);
}
function verifySignedValue(string $signed): ?string
{
    $position = strrpos($signed, '.');
    if ($position === false) {
        return null;
    }
    $value = substr($signed, 0, $position);
    $signature = substr($signed, $position + 1);
    return hash_equals(hash_hmac('sha256', $value, COOKIE_SECRET), $signature) ? $value : null;
}
$cookie = signValue('dark');
var_dump(verifySignedValue($cookie));
var_dump(verifySignedValue('light.' . substr($cookie, 5)));
var_dump(verifySignedValue('dark'));

Output

string(4) "dark"
NULL
NULL

How It Works

  1. hash_hmac() computes a signature from the value and a secret key that only the server knows.
  2. The cookie stores value.signature.
  3. When reading, the server recomputes the signature for the value. If the user changed the value (here, dark to light) without knowing the secret, the signatures no longer match.
  4. hash_equals() compares the signatures in constant time, which prevents timing attacks. Signing prevents modification, but the value is still readable. Sensitive data does not belong in cookies at all — store it in the session or database.

RuleDetail
SizeAbout 4 KB per cookie (name + value + attributes)
NumberBrowsers limit the number of cookies per domain (commonly 50 or more)
Sent with every requestLarge cookies slow down every request, including images and CSS on the same domain
__Host- name prefixBrowsers accept the cookie only if it is secure, has path=/, and has no domain — a strong protection for important cookies
Privacy lawsNon-essential cookies (analytics, advertising) may require user consent, depending on the jurisdiction

Common Mistakes

Effect: $_COOKIE['theme'] is not set right after setcookie(). Fix: Use the value you just set directly, or redirect so the next request carries the cookie.

Calling setcookie() After Output

Effect: "Headers already sent" warning, and the cookie is not set. Fix: Set cookies before any output; omit closing ?> in pure PHP files.

Storing Sensitive Data in Cookies

Effect: User IDs, roles, or prices can be read or changed by the user. Fix: Store an opaque session ID only; keep data on the server.

Forgetting Security Options

Effect: Cookies readable by JavaScript or sent over HTTP. Fix: Use secure, httponly, and samesite.

Deleting With Different path/domain

Effect: The cookie is not removed. Fix: Use the same attributes as when setting it.


Best Practices

  • Use the options array with secure, httponly, and samesite for every cookie.
  • Treat $_COOKIE as untrusted input: use defaults, allow-lists, and type checks.
  • Keep cookies small; store complex data server-side.
  • Sign cookies whose values must not be modified, and never put secrets in them.
  • Set cookies before any output, and remember they appear in $_COOKIE only on the next request. Official reference: https://www.php.net/manual/en/reserved.variables.cookies.php

0 Comments

Reviewed before they appear

No comments yet.

Data Mining
Introduction to Data Mining Data Mining Implementation Process Data Mining Architecture Data Mining Techniques KDD: Knowledge Discovery in Databases History of Data Mining Data Mining Tools Data Mining vs Machine Learning Facebook Data Mining Social Media Data Mining Methods Clustering in Data Mining Text Data Mining Bagging vs Boosting Data Mining vs Data Warehousing Social Media Data Mining Data Mining: Bayesian Classifiers Data Mining: World Wide Web Different Types of Clustering Bitcoin Mining and Blockchain Data Mining Orange Data Mining Data Mining vs Big Data Decision Tree Induction Educational Data Mining Data Mining in Healthcare Apriori Algorithm Data Integration in Data Mining Difference Between Data Mining and Text Mining Discretization in Data Mining Redundancy and Correlation in Data Mining Classification of Data Mining Systems Classification Algorithms in Data Mining Data Generalization in Data Mining Classification and Prediction in Data Mining Regression in Data Mining What Is an Outlier in Data Mining Data Cleaning in Data Mining Data Processing in Data Mining Data Mining Task Primitives Web Content Mining, Web Structure Mining, and Web Usage Mini Binning in Data Mining KDD vs. Data Mining Noise in Data Mining BIRCH in Data Mining Stemming in Data Mining Feature Transformation in Data Mining Visual and Audio Data Mining Class Comparison Methods in Data Mining Data Selection in Data Mining Tasks and Functionalities of Data Mining Ubiquitous and Invisible Data Mining Importance of Data Mining Data Quality in Data Mining Mining Frequent Patterns in Data Mining Data Warehouse and OLAP Technology for Data Mining Need for Data Mining Pattern Evaluation Methods in Data Mining Logarithms and Exponents in Complexity Analysis Time Series Clustering What is the C4.5 Algorithm and How Does It Work? Expanding Contractions in Text Mining Cosine Similarity in Data Mining Lazy Learning in Data Mining Neural Networks in Data Mining Building a Text Normalizer Shallow Parsing Data Pipeline Orchestration Big Data vs Small Data Myths of Data Mining Data Reduction in Data Mining Data Mining Models Difference Between Data Mining and Data Science Difference Between Data Mining and Statistics Difference Between Data Mining and Web Mining Difference Between Data Mining and Data Analysis Difference Between Business Intelligence and Data Mining Difference Between Data Mining and Data Visualization Data Mining vs Data Analytics Types of Data Mining Difference Between Data Profiling and Data Mining Predictive Analytics vs Data Mining Difference Between Data Mining and OLAP Descriptive and Predictive Data Mining Difference Between Spatial and Temporal Data Mining Difference Between Classification and Clustering in Data Min Hierarchical Clustering in Data Mining Density-Based Clustering in Data Mining What Is Aggregation in Data Mining?
Ask about this post
AI Ask about this post

Ask questions about $_COOKIE and get answers drawn from it.

Signed-in readers only.