Cookies sent by the browser arrive in $_COOKIE. Reading them is easy. Reading them safely takes a little care.
Check that it exists
<?php
$_COOKIE = ["lang" => "hi"];
if (isset($_COOKIE["lang"])) {
echo "Language cookie: " . $_COOKIE["lang"];
} else {
echo "No language chosen";
}
Language cookie: hi
Shorter, with a default:
<?php
$_COOKIE = [];
$lang = $_COOKIE["lang"] ?? "en";
echo $lang;
en
Validate the value
The value is whatever the browser sent. Compare it with the values you accept.
<?php
$_COOKIE = ["lang" => "../../etc"];
$supported = ["en", "hi", "ta"];
$lang = in_array($_COOKIE["lang"] ?? "", $supported, true) ? $_COOKIE["lang"] : "en";
echo $lang;
en
Numbers
<?php
$_COOKIE = ["font_size" => "99999"];
$size = filter_var($_COOKIE["font_size"] ?? 16, FILTER_VALIDATE_INT, [
"options" => ["min_range" => 12, "max_range" => 32, "default" => 16],
]);
echo $size;
16
Escape on output
If you print a cookie value into HTML, escape it.
<?php
$_COOKIE = ["name" => '"><script>alert(1)</script>'];
echo htmlspecialchars($_COOKIE["name"] ?? "");
"><script>alert(1)</script>
Array cookies
A cookie named prefs[color] becomes a nested array in $_COOKIE. A visitor can also send an array where you expect a string. Check with is_string() first.
Cookies with the same name
If a browser sends two cookies with the same name (from different paths), PHP uses only one of them. If you see strange behaviour, check the path and domain of each cookie in the developer tools.
When a cookie does not arrive
- The cookie has expired or the user deleted it.
- The
pathordomaindoes not match the page. secureis set, but the page uses plain HTTP.- Cookies are blocked in the browser.
- The cookie was set on this same request (it arrives on the next one).