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, который PHP отправит клиенту вместе с остальными HTTP-заголовками. Как и другие заголовки, блоки данных cookies требуется отправлять до вывода скрипта (это ограничение протокола). Поэтому требуется вызывать функцию перед любым выводом, включая вывод тегов <html> и <head>, а также пустые строки и пробельные символы.

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

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

Стандарт » RFC 6265 даёт нормативные ссылки на интерпретацию значений каждого параметра функции setcookie().

name

Название cookie.

value

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

expires_or_options

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

Замечание:

Видно, что параметр expires_or_options принимает значение как метку времени Unix, а хранит значение в формате 'Wdy, DD-Mon-YYYY HH:MM:SS GMT', причина состоит в том, что PHP преобразовывает значение автоматически.

path

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

domain

Домен или поддомен, у которого будет доступ к блоку данных cookie. При установке параметра на поддомен www.example.com сервер откроет доступ к cookie для этого поддомена и каждого его поддомена наподобие w2.www.example.com. Чтобы открыть доступ к cookie для всего домена с поддоменами, нужно просто указать имя домена (для этого примера — example.com).

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

secure

Указывает, что передавать блок данных cookie от клиента требуется только по защищённому HTTPS-соединению. PHP установит cookie только через безопасное соединение, если для параметра установили значение true. За отправку cookie с сервера только через безопасное соединение отвечает программист. Безопасно ли подключение, узнают, например, по значению суперглобальной переменной $_SERVER["HTTPS"].

httponly

PHP предоставит доступ к cookie только через HTTP-протокол, если для параметра установили значение true. Это означает, что скриптовые языки наподобие JavaScript не получат доступа к cookie. Отдельные программисты высказывали предположение, что этот параметр в состоянии эффективно сократить количество краж личных данных через XSS-атаки (хотя параметр поддерживается не каждым браузером), но это утверждение часто оспаривается. Параметр принимает значение true или false.

options

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

Замечание:

Блок данных cookie с атрибутами, которых нет в списке ключей, устанавливают функцией 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", true);

?>

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

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

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

Добавить

Примечания пользователей 13 notes

up
388
walterquez
12 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
266
Bachsau
12 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
89
Anonymous
4 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
35
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
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
17
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
synnus at gmail dot com
4 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
8
ellert at vankoperen dot nl
10 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
4
laffen
15 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
3
Anonymous
14 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
ilya at ilya dot top
3 months ago
In any web browser there is a very commonly used option "Open previous windows and tabs" which is disabled by default, but many people enable it.
When this option is active, the web browser, when closing and reopening, instead of executing the termination and starting a new session, saves and restores the current session along with session cookies and sessionStorage.
Both session cookies and sessionStorage, contrary to expectations, can live for a very long time until the user closes the tab before closing the web browser.
If you want a cookie, for example with a time offset, to be guaranteed to have a short lifetime, you should explicitly specify this short lifetime, rather than relying on self-deletion on the session cookie.
up
-1
hansel at gretel dot com
18 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