CakeFest 2024: The Official CakePHP Conference

setcookie

(PHP 4, PHP 5, PHP 7, PHP 8)

setcookieОтправляет cookie

Описание

setcookie(
    string $name,
    string $value = "",
    int $expires_or_options = 0,
    string $path = "",
    string $domain = "",
    bool $secure = false,
    bool $httponly = false
): bool

Альтернативная сигнатура доступна с PHP 7.3.0 (именованные параметры не поддерживаются):

setcookie(string $name, string $value = "", array $options = []): bool

Функция setcookie() задаёт значение cookie, которое будет отправлено клиенту вместе с другими HTTP-заголовками. Как и другие заголовки, файл cookie должен передаваться до того, как будут выведены любые другие данные скрипта (это ограничение протокола). Для этого нужно вызывать функцию до остального вывода, включая вывод тегов <html> и <head>, а также пустые строки и пробельные символы.

После установки cookie к нему можно будет получить доступ через суперглобальную переменную $_COOKIE при следующей загрузке страницы. Значения cookie также может содержать суперглобальная переменная $_REQUEST.

Список параметров

Стандарт » RFC 6265 даёт конкретные указания о том, как нужно интерпретировать каждый из параметров setcookie().

name

Название cookie.

value

Значение cookie. Это значение будет сохранено на клиентском компьютере; не записывайте в cookie секретные данные. Значение, присвоенное cookie c именем name, допустим, 'cookiename', будет доступно через $_COOKIE['cookiename'].

expires_or_options

Время истечение срока действия cookie. Это метка времени Unix, то есть количество секунд с начала эпохи. Один из способов установить значение — добавить количество секунд до истечения срока действия cookie к результату вызова функции time(). Например, выражение time() + 60 * 60 * 24 * 30 установит срок действия cookie, который закончится через 30 дней. Другой вариант — вызвать функцию mktime(). Если задать 0 или пропустить аргумент, срок действия cookie закончится с окончанием сессии (при закрытии браузера).

Замечание:

Можно заметить, что параметр expires_or_options принимает в качестве значения метку времени Unix, а хранит его в формате Wdy, DD-Mon-YYYY HH:MM:SS GMT, причина этому то, что PHP делает это преобразование автоматически.

path

Путь на сервере, по которому будут доступны значения cookie. Если задать «/», cookie будут доступны во всем домене domain. Если задать «/foo/», cookie будут доступны только из директории /foo/ и её поддиректорий (например, /foo/bar/) домена domain. Значение по умолчанию — текущая директория, в которой PHP устанавливает cookie.

domain

Домен или поддомен, которому доступны cookie. Задание поддомена (например, «www.example.com») сделает cookie доступными в нём и во всех поддоменах (например, w2.www.example.com). Чтобы сделать cookie доступными для всего домена, включая поддомены, нужно просто указать имя домена (то есть «example.com»).

Старые браузеры, следующие устаревшему стандарту » RFC 2109, могут требовать . перед доменом, чтобы включались все поддомены.

secure

Указывает на то, что значение cookie должно передаваться от клиента по защищённому соединению HTTPS. Если задано true, cookie от клиента будут переданы на сервер, только если установлено защищённое соединение. При передаче cookie от сервера клиенту программист веб-сервера должен следить за тем, чтобы cookie этого типа передавались по защищённому каналу (например, с учётом значения суперглобальной переменной $_SERVER["HTTPS"]).

httponly

Если задано true, cookie будут доступны только через HTTP-протокол. То есть cookie не будут доступны скриптовым языкам наподобие JavaScript. Было высказано предположение, что этот параметр в состоянии эффективно уменьшить кражу личных данных через XSS-атаку (хотя он поддерживается не всеми браузерами), но это утверждение часто оспаривается. Может принимать значения true или false.

options

Ассоциативный массив (array), который может содержать любой из ключей: expires, path, domain, secure, httponly и samesite. Если в массиве окажется другой ключ, будет выдана ошибка уровня E_WARNING. Значения имеют тот же смысл, который описан для параметров с тем же именем. Значение элемента samesite должно быть либо None, либо Lax или Strict. Если какая-то из разрешённых опций не указана, её значения по умолчанию совпадают с значениями по умолчанию явных параметров. Если элемент samesite не указан, функция не установит cookie-атрибут SameSite.

Замечание:

To set a cookie that includes attributes that aren't among the keys listed, use header().

Возвращаемые значения

Если перед вызовом функции клиенту уже передавался какой-либо вывод (теги, пустые строки, пробелы, текст и т.п.), setcookie() потерпит неудачу и вернёт false. Если setcookie() успешно отработает, то вернёт true. Это, однако, не означает, что клиентское приложение (браузер) правильно приняло и обработало cookie.

Список изменений

Версия Описание
8.2.0 Формат даты отправляемых cookie теперь «D, d M Y H:i:s \G\M\T»; ранее он был «D, d-M-Y H:i:s T».
7.3.0 Добавлена альтернативная подпись, поддерживающая массив опций options. Эта подпись поддерживает также настройку cookie-атрибута SameSite.

Примеры

Следующие примеры иллюстрируют ряд способов отправки cookies.

Пример #1 Пример использования setcookie()

<?php

$value
= 'что-то откуда-то';

setcookie("TestCookie", $value);
setcookie("TestCookie", $value, time()+3600); /* срок действия 1 час */
setcookie("TestCookie", $value, time()+3600, "/~rasmus/", "example.com", 1);

?>

Стоит отметить, что значение cookie перед отправкой клиенту подвергается URL-кодированию. При обратном получении значение cookie декодируется и помещается в переменную, с тем же именем, что и имя cookie. Если вы не хотите, чтобы значения кодировались, используйте функцию setrawcookie(). Посмотреть содержимое наших тестовых cookie можно, запустив один из следующих примеров:

<?php
// Вывести одно конкретное значение cookie
echo $_COOKIE["TestCookie"];

// В целях тестирования и отладки может пригодиться вывод всех cookie
print_r($_COOKIE);
?>

Пример #2 Пример удаления cookie посредством setcookie()

Чтобы удалить cookie достаточно в качестве срока действия указать какое-либо время в прошлом. Это запустит механизм браузера, удаляющий истёкшие cookie. В примерах ниже показано, как удалить cookie, заданные в предыдущих примерах:

<?php
// установка даты истечения срока действия на час назад
setcookie("TestCookie", "", time() - 3600);
setcookie("TestCookie", "", time() - 3600, "/~rasmus/", "example.com", 1);
?>

Пример #3 setcookie() и массивы

Имеется возможность помещать в cookie массивы. Для этого каждому cookie нужно дать имя в соответствии с правилами именования массивов. Такая возможность позволяет поместить столько значений, сколько имеется элементов в массиве. При обратном получении все эти значения будут помещены в массив с именем этого cookie:

<?php
// отправка cookie
setcookie("cookie[three]", "cookiethree");
setcookie("cookie[two]", "cookietwo");
setcookie("cookie[one]", "cookieone");

// после перезагрузки страницы, выведем cookie
if (isset($_COOKIE['cookie'])) {
foreach (
$_COOKIE['cookie'] as $name => $value) {
$name = htmlspecialchars($name);
$value = htmlspecialchars($value);
echo
"$name : $value <br />\n";
}
}
?>

Результат выполнения приведённого примера:

three : cookiethree
two : cookietwo
one : cookieone

Замечание: Указание символов-разделителей наподобие [ и ] в составе имени cookie не соответствует 4-му разделу стандарта RFC 6265, но должно поддерживаться агентами пользователя, как указано в разделе 5 стандарта RFC 6265.

Примечания

Замечание:

Разрешено буферизировать вывод для отправки вывода до вызова этой функции, при этом вывод в браузер буферизируется на сервере до тех пор, пока не будет отпрален. Это делают вызовом в скрипте функций ob_start() и ob_end_flush(), либо включают директиву конфигурации output_buffering в файле php.ini или в файлах конфигурации сервера.

Общие замечания:

  • Cookie станут видимыми только после перезагрузки страницы, для которой они должны быть видны. Для проверки, правильно ли установлены cookie, их проверяют при следующей загрузке страницы до истечения их срока действия. Срок действия cookie задают в параметре expires_or_options. Хороший способ отладить наличие файлов cookie — просто вызывать функцию print_r($_COOKIE);.
  • При удалении cookie должны быть заданы те же параметры, что и при установке. Если в качестве значения задать пустую строку, а остальные параметры соответствуют предыдущему вызову функции setcookie, то cookie c заданным именем будет удалён на удалённом клиенте. Внутренне это выглядит так: cookie будет присвоено значение «deleted», а срок действия переносится на год в прошлое.
  • Поскольку установка значения false приведёт к удалению cookie, не нужно задавать cookie логические значения. Вместо этого можно указать 0 для false и 1 для true.
  • Имена cookie разрешено устанавливать массивом имён, которые будут доступны в PHP-скрипте как массивы, но в системе пользователя они будут храниться в виде отдельных записей. Для задания cookie c несколькими именами и значениями рекомендовано вызывать функцию explode(). Не рекомендовано пользоваться для этих целей функцией serialize(), поскольку это нарушает безопасность.

Множественные вызовы функции setcookie() выполняются в порядке вызова.

Смотрите также

add a note

User Contributed Notes 12 notes

up
390
walterquez
11 years ago
Instead of this:
<?php setcookie( "TestCookie", $value, time()+(60*60*24*30) ); ?>

You can this:
<?php setcookie( "TestCookie", $value, strtotime( '+30 days' ) ); ?>
up
259
Bachsau
11 years ago
Want to remove a cookie?

Many people do it the complicated way:
setcookie('name', 'content', time()-3600);

But why do you make it so complicated and risk it not working, when the client's time is wrong? Why fiddle around with time();

Here's the easiest way to unset a cookie:
setcookie('name', 'content', 1);

Thats it.
up
87
Anonymous
3 years ago
Just an example to clarify the use of the array options, especially since Mozilla is going to deprecate / penalise the use of SameSite = none, which is used by default if not using array options.

<?php
$arr_cookie_options
= array (
'expires' => time() + 60*60*24*30,
'path' => '/',
'domain' => '.example.com', // leading dot for compatibility or use subdomain
'secure' => true, // or false
'httponly' => true, // or false
'samesite' => 'None' // None || Lax || Strict
);
setcookie('TestCookie', 'The Cookie Value', $arr_cookie_options);
?>
up
36
paul nospam AT nospam sitepoint dot com
17 years ago
Note when setting "array cookies" that a separate cookie is set for each element of the array.

On high traffic sites, this can substantially increase the size of subsequent HTTP requests from clients (including requests for static content on the same domain).

More importantly though, the cookie specification says that browsers need only accept 20 cookies per domain. This limit is increased to 50 by Firefox, and to 30 by Opera, but IE6 and IE7 enforce the limit of 20 cookie per domain. Any cookies beyond this limit will either knock out an older cookie or be ignored/rejected by the browser.
up
21
nacho at casinelli dot com
7 years ago
It's worth a mention: you should avoid dots on cookie names.

<?php
// this will actually set 'ace_fontSize' name:
setcookie( 'ace.fontSize', 18 );
?>
up
13
synnus at gmail dot com
3 years ago
The " PHPSESSID " cookie will soon be rejected because its " sameSite " attribute is set to " none " or an invalid value, and without " secure " attribute. To learn more about the "sameSite" attribute, visit https://developer.mozilla.org/docs/Web/HTTP/Headers/Set-Cookie/SameSite.

<?php
ini_set
("session.cookie_secure", 1);
session_start();

my PHP code ....

?>
up
42
Anonymous
17 years ago
something that wasn't made clear to me here and totally confused me for a while was that domain names must contain at least two dots (.), hence 'localhost' is invalid and the browser will refuse to set the cookie! instead for localhost you should use false.

to make your code work on both localhost and a proper domain, you can do this:

<?php

$domain
= ($_SERVER['HTTP_HOST'] != 'localhost') ? $_SERVER['HTTP_HOST'] : false;
setcookie('cookiename', 'data', time()+60*60*24*365, '/', $domain, false);

?>
up
19
gabe at fijiwebdesign dot com
17 years ago
If you want to delete all cookies on your domain, you may want to use the value of:

<?php $_SERVER['HTTP_COOKIE'] ?>

rather than:

<?php $_COOKIE ?>

to dertermine the cookie names.
If cookie names are in Array notation, eg: user[username]
Then PHP will automatically create a corresponding array in $_COOKIE. Instead use $_SERVER['HTTP_COOKIE'] as it mirrors the actual HTTP Request header.

<?php

// unset cookies
if (isset($_SERVER['HTTP_COOKIE'])) {
$cookies = explode(';', $_SERVER['HTTP_COOKIE']);
foreach(
$cookies as $cookie) {
$parts = explode('=', $cookie);
$name = trim($parts[0]);
setcookie($name, '', time()-1000);
setcookie($name, '', time()-1000, '/');
}
}

?>
up
9
ellert at vankoperen dot nl
9 years ago
Caveat: if you use URL RewriteRules to get stuff like this: domain.com/bla/stuf/etc into parameters, you might run into a hickup when setting cookies.
At least in my setup a change in one of the parameters resulted in the cookie not being 'there' anymore.
The fix is simple: specify the domain. '/' will usualy do fine.
up
6
laffen
14 years ago
Note that the $_COOKIE variable not will hold multiple cookies with the same name. It is legitimate to set two cookies with the same name to the same host where the sub domain is different.
<?php
setcookie
("testcookie", "value1hostonly", time(), "/", ".example.com", 0, true);
setcookie("testcookie", "value2subdom", time(), "/", "subdom.example.com", 0, true);
?>
The next request from the browser will have both cookies in the $_SERVER['HTTP_COOKIE'] variable, but only one of them will be found in the $_COOKIE variable. Requests to subdom.example.com will have both cookies, while browser request to example.com or www.example.com only sends the cookie with the "value1hostonly" value.

<?php
$kaker
= explode(";", $_SERVER['HTTP_COOKIE']);
foreach(
$kaker as $val){
$k = explode("=", $val);
echo
trim($k[0]) . " => " . $k[1];
}

// output
testcookie => value1hostonly
testcookie
=> value2subdom

?>
up
2
Anonymous
13 years ago
A period in a cookie name (like user.name) seems to show up in the $_COOKIE array as an underscore (so user_name). This means that for example $_COOKIE["user_name"] must be used to read a cookie that has been set with setcookie("user.name" ...), which is already rather confusing.

Furthermore the variable $_COOKIE["user_name"] will retain the value set by setcookie("user.name" ...) and no amount of calling setcookie("user_name" ...) will alter this value. This is rather trivially fixed by clearing the "user.name" cookie, but it can take a while to realize this since there's only "user_name" in $_COOKIE.

Hope this saves someone some time.
up
0
hansel at gretel dot com
17 years ago
The following code snippet combines abdullah's and Charles Martin's examples into a powerful combination function (and fixes at least one bug in the process):

<?php
function set_cookie_fix_domain($Name, $Value = '', $Expires = 0, $Path = '', $Domain = '', $Secure = false, $HTTPOnly = false)
{
if (!empty(
$Domain))
{
// Fix the domain to accept domains with and without 'www.'.
if (strtolower(substr($Domain, 0, 4)) == 'www.') $Domain = substr($Domain, 4);
$Domain = '.' . $Domain;

// Remove port information.
$Port = strpos($Domain, ':');
if (
$Port !== false) $Domain = substr($Domain, 0, $Port);
}

header('Set-Cookie: ' . rawurlencode($Name) . '=' . rawurlencode($Value)
. (empty(
$Expires) ? '' : '; expires=' . gmdate('D, d-M-Y H:i:s', $Expires) . ' GMT')
. (empty(
$Path) ? '' : '; path=' . $Path)
. (empty(
$Domain) ? '' : '; domain=' . $Domain)
. (!
$Secure ? '' : '; secure')
. (!
$HTTPOnly ? '' : '; HttpOnly'), false);
}
?>

Basically, if the domain parameter is supplied, it is converted to support a broader range of domains. This behavior may or may not be desireable (e.g. could be a security problem depending on the server) but it makes cookie handling oh-so-much-nicer (IMO).
To Top