setcookie() tells the browser to store a cookie. The modern way uses an options array.
<?php
setcookie("theme", "dark", [
"expires" => time() + 60 * 60 * 24 * 30, // 30 days
"path" => "/",
"secure" => true, // HTTPS only
"httponly" => true, // hidden from JavaScript
"samesite" => "Lax",
]);
Call it before any output
Cookies are sent in the HTTP headers, so setcookie() must run before any output, just like session_start() and header(). Otherwise PHP warns “headers already sent”, and the cookie is not sent.
The options
| Option | Meaning |
|---|---|
expires | A Unix timestamp. 0 means “until the browser closes” |
path | Where the cookie applies. "/" for the whole site |
domain | Usually leave out |
secure | true sends only over HTTPS |
httponly | true blocks JavaScript access |
samesite | "Lax", "Strict" or "None" (None needs secure) |
The value is not in $_COOKIE yet
The cookie goes to the browser with the response. PHP fills $_COOKIE from the request. So the new cookie appears in $_COOKIE only on the next page load.
<?php
setcookie("seen", "yes", ["path" => "/"]);
var_dump(isset($_COOKIE["seen"])); // false on the first visit
If you need the value now, store it in a variable too.
Time helpers
<?php
$expires = time() + 60 * 60 * 24 * 7; // 7 days from now
echo round(($expires - time()) / 86400) . " days";
7 days
Encode values
setcookie() URL-encodes the value for you. setrawcookie() does not, so avoid it unless you know why you need it.
Choose the right SameSite value
Laxis a good default: cookies are sent when the user clicks a link to your site, but not on most cross-site requests.Strictis stronger, but a cookie is not sent when someone arrives from another site by a link. A user opening your site from an email can appear logged out.Nonesends the cookie in all cross-site requests. It requiressecure => true.
A preference cookie with validation
<?php
function themeFromCookie(array $cookies): string
{
$allowed = ["light", "dark"];
return in_array($cookies["theme"] ?? "", $allowed, true) ? $cookies["theme"] : "light";
}
echo themeFromCookie(["theme" => "dark"]) . " ";
echo themeFromCookie(["theme" => "<script>"]);
dark light