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, для которого через параметр name установили название 'cookiename', извлекают из элемента $_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. При установке значения '/foo/' cookie отправляются только при обращении к каталогу /foo/ в домене domain и подкаталогам наподобие /foo/bar/. По умолчанию cookie устанавливается для текущего каталога.
domain
Домен или поддомен, для которого требуется установить cookie. При установке значения 'www.example.com' cookie отправятся в запросах к поддомену и поддоменам вроде w2.www.example.com. Для установки cookie для домена и поддоменов указывают имя домена: 'example.com'. Старым браузерам, которые до сих пор следуют устаревшему стандарту » RFC 2109, требуется символ . перед доменом для сопоставления с поддоменами.
secure
Указывает, что передавать cookie от клиента требуется только по защищённому HTTPS-соединению. При установке значения true cookie передаются только через безопасное соединение. За отправку cookie с сервера только через безопасное соединение отвечает программист. Безопасно ли соединение, узнают, например, по значению элемента $_SERVER["HTTPS"].
httponly
Значение true разрешает передачу cookie только по протоколу HTTP и закрывает доступ к cookie скриптовым языкам наподобие JavaScript. Отдельные разработчики высказывали предположение о снижении параметром риска краж личных данных через XSS-атаки. При этом не каждый браузер поддерживает параметр, а утверждение часто оспаривается. Параметр принимает значение true или false.
options
Ассоциативный массив (array) с произвольным набором ключей: expires, path, domain, secure, httponly и samesite. Смысл элементов массива аналогичен одноимённым параметрам. Элемент samesite принимает только следующие значения: None, Lax или Strict. Пропущенные элементы массива опций получают значение по умолчанию параметра. При пропуске элемента samesite cookie-атрибут SameSite не устанавливается.

Замечание: Cookie с атрибутами вне списка ключей устанавливают функцией header().

Замечание: При установке для элемента samesite значения "None" потребуется также включить элемент secure, иначе клиент заблокирует cookie.

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

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

Ошибки

При включении в массив options ключей, которые параметр не поддерживает:

  • До PHP 8.0.0 функция генерирует ошибку уровня E_WARNING.
  • С PHP 8.0.0 функция выбрасывает ошибку ValueError.

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

Версия Описание
8.2.0 Дата cookie теперь устанавливается в формате 'D, d M Y H:i:s \G\M\T'; раньше дата устанавливалась в формате 'D, d-M-Y H:i:s T'.
8.0.0 При передаче в массиве опций ключей, которые параметр не поддерживает, теперь выбрасывается ошибка ValueError; раньше функция выдавала ошибку уровня E_WARNING.
7.3.0 Добавили альтернативную сигнатуру, которая поддерживает массив опций options. Эта сигнатура поддерживает также установку cookie-атрибута SameSite.

Примеры

Результаты следующих примеров видны в списке блоков данных cookie в инструментах разработчика браузера на вкладке Storage или Application.

Пример #1 Пример отправки cookie функцией setcookie()

<?php

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

// Установка «сессионного блока cookie», срок действия которого истекает при закрытии браузера
setcookie("TestCookie", $value);

// Установка cookie сроком на 1 час
setcookie("TestCookie", $value, time() + 3600);

// Установка cookie, который применяется только к конкретному пути конкретного домена.
// Замечание: браузер отклонит cookie, если домен в пути cookie не совпадёт с доменом сайта
setcookie("TestCookie", $value, time() + 3600, "/~rasmus/", "example.com", true);

PHP автоматически кодирует и декодирует cookie по правилам безопасного форматирования URL-адресов. Функция setrawcookie() отправляет cookie без кодирования.

Следующий пример при очередном запросе покажет содержание cookies, которые установили в предыдущем примере:

<?php

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

// Вывод всех cookie для тестирования или отладки
print_r($_COOKIE);

Пример #2 Пример удаления cookie функцией setcookie()

Для удаления cookie дату истечения срока действия устанавливают как значение в прошлом, но не на ноль — значение зарезервировали для сессионных cookie.

Следующий пример удалит cookies, которые установили в предыдущем примере:

<?php

// Установка даты истечения срока действия на час в прошлом
setcookie("TestCookie", "", time() - 3600);
setcookie("TestCookie", "", time() - 3600, "/~rasmus/", "example.com", 1);

Пример #3 Пример отправки массива cookies функцией setcookie()

Для установки «массива cookies» название 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 или через файлы конфигурации сервера.

Предостережения:

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

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

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

Добавить

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

up
397
walterquez
13 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
277
Bachsau
13 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
95
Anonymous
5 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
24
nacho at casinelli dot com
8 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
36
paul nospam AT nospam sitepoint dot com
19 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
43
Anonymous
19 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
2
ilya at ilya dot top
1 year 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
16
gabe at fijiwebdesign dot com
19 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
7
synnus at gmail dot com
5 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
6
ellert at vankoperen dot nl
11 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
3
Anonymous
15 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
3
laffen
16 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
0
alexsvetalena at mail dot ru
7 months ago
Please keep in mind that if you call setcookie() several times during the script execution (even for the same name, domain and path), then Set-Cookie header will be sent several times, and only after receiving all of them, client browser will "merge" them, replacing first value for the cookie with the next etc.

This may cause very large headers length sometimes, so you'll have to either increase buffers for your web server; change your code logic to determine all possibly-changing parameters values right from the start; implement some sort of global Response object keeping all the data, including cookies as well, till the end of processing (sort of optimized output beffering); or just avoid storing any large data in cookies.
up
-2
steven at sovstack dot com
1 year ago
As of PHP 7.3, you can use this syntax:

setcookie( $name,  $value,  $options)

Be aware that the array in $options is not fully compatible with array key names. In other words, the order of your array values matters regardless of the array key names.

<?PHP

// Correct (with key names):
setcookie(
    'my_cookie',
    'my_value',
    [
        'expires' => time() + 3600,
        'path' => '/',
    ]
);

// Correct (without key names):
setcookie(
    'my_cookie',
    'my_value',
    [
        time() + 3600, // expires
        '/' // path
    ]
);

// Incorrect Usage (wrong order as key names are ignored):
setcookie(
    'my_cookie',
    'my_value',
    [
        'path' => '/', // WRONG: should be 2nd
        'expires' => time() + 3600, // WRONG: should be 1st
    ]
);

// Here's the correct order of the $options array with default values:
$options = [
    'expires' => 0,
    'path' => "",
    'domain' => "",
    'secure' => false,
    'httponly' => false
];

setcookie(
    'my_cookie',
    'my_value',
    $options 
);

?>

If you do not provide options, the default values will be used.
To Top